{"id":26073,"date":"2026-08-04T12:20:01","date_gmt":"2026-08-04T10:20:01","guid":{"rendered":"https:\/\/telemedi.com\/?page_id=26073"},"modified":"2026-08-04T13:02:47","modified_gmt":"2026-08-04T11:02:47","slug":"uzupelnij-wniosek-refundacyjny","status":"publish","type":"page","link":"https:\/\/telemedi.com\/pl\/formularz-refundacji\/uzupelnij-wniosek-refundacyjny\/","title":{"rendered":"Uzupe\u0142nij wniosek refundacyjny"},"content":{"rendered":"\n<style data-wp-block-html=\"css\">\n\n\t\/* Deliberately useless first rule \u2014 a fuse, not dead code. If a stray tag (an\n\t   opening style or link) ever lands at the top of the WordPress CSS field, the\n\t   CSS parser swallows that garbage TOGETHER WITH the first rule after it. Let it\n\t   eat the decoy instead of the page background. Do not move, do not remove. *\/\n\t.tw-css-field-guard { display: none; }\n\n\tbody {\n\t  background-color: #f0f4f8;\n   }\n\t#form__wrapper, .header .container {\n\t\tbackground-color: #f0f4f8;\n\t}\n\n\t\/* Mniejsze boczne marginesy na mobile - sekcje \"dotykaj\u0105\" kraw\u0119dzi ekranu *\/\n\t@media (max-width: 640px) {\n\t\t#form__wrapper.p-8 {\n\t\t\tpadding-left: 0.5rem;\n\t\t\tpadding-right: 0.5rem;\n\t\t}\n\t}\n\t\n\t.spinner-border {\n\t\tdisplay: none;\n\t\twidth: 1.5rem;\n\t\theight: 1.5rem;\n\t\tborder: 0.25em solid currentColor;\n\t\tborder-right-color: transparent;\n\t\tborder-radius: 50%;\n\t\tanimation: spinner-border .75s linear infinite;\n\t}\n\t\n\t.spinner-border.show {\n\t\tdisplay: inline-block;\n\t}\n\t\n\t@keyframes spinner-border {\n\t\tto { transform: rotate(360deg); }\n\t}\n\t\n\t\/* Customowy modal\/popup *\/\n\t.custom-modal {\n\t\tdisplay: none;\n\t\tposition: fixed;\n\t\tz-index: 1000;\n\t\tleft: 0;\n\t\ttop: 0;\n\t\twidth: 100%;\n\t\theight: 100%;\n\t\tbackground-color: rgba(0, 0, 0, 0.5);\n\t\tbackdrop-filter: blur(3px);\n\t}\n\t\n\t.custom-modal.show {\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\t}\n\t\n\t.modal-content {\n\t\tbackground-color: white;\n\t\tborder-radius: 12px;\n\t\tbox-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);\n\t\tmax-width: 500px;\n\t\twidth: 90%;\n\t\tmax-height: 80vh;\n\t\toverflow-y: auto;\n\t\tanimation: modalSlideIn 0.3s ease-out;\n\t\tmargin: 20px;\n\t}\n\t\n\t@media (max-width: 640px) {\n\t\t.modal-content {\n\t\t\twidth: 95%;\n\t\t\tmargin: 10px;\n\t\t\tmax-height: 90vh;\n\t\t}\n\t\t\n\t\t.modal-header {\n\t\t\tpadding: 16px 20px 0 20px;\n\t\t}\n\t\t\n\t\t.modal-body {\n\t\t\tpadding: 16px 20px;\n\t\t}\n\t\t\n\t\t.modal-footer {\n\t\t\tpadding: 0 20px 16px 20px;\n\t\t}\n\t}\n\t\n\t.modal-header {\n\t\tpadding: 20px 24px 0 24px;\n\t\tborder-bottom: 1px solid #e5e7eb;\n\t}\n\t\n\t.modal-body {\n\t\tpadding: 20px 24px;\n\t\tcolor: #374151;\n\t\tline-height: 1.6;\n\t}\n\t\n\t.modal-footer {\n\t\tpadding: 0 24px 20px 24px;\n\t\tdisplay: flex;\n\t\tjustify-content: flex-end;\n\t}\n\t\n\t.modal-close-btn {\n\t\tbackground-color: #ef4444;\n\t\tcolor: white;\n\t\tborder: none;\n\t\tpadding: 10px 20px;\n\t\tborder-radius: 8px;\n\t\tcursor: pointer;\n\t\tfont-weight: 600;\n\t\ttransition: background-color 0.2s;\n\t}\n\t\n\t.modal-close-btn:hover {\n\t\tbackground-color: #dc2626;\n\t}\n\t\n\t@keyframes modalSlideIn {\n\t\tfrom {\n\t\t\topacity: 0;\n\t\t\ttransform: scale(0.9) translateY(-20px);\n\t\t}\n\t\tto {\n\t\t\topacity: 1;\n\t\t\ttransform: scale(1) translateY(0);\n\t\t}\n\t}\n\t\n\t.modal-icon {\n\t\tfont-size: 48px;\n\t\tmargin-bottom: 16px;\n\t\ttext-align: center;\n\t}\n\t\n\t.modal-icon.error {\n\t\tcolor: #ef4444;\n\t}\n\t\n\t.modal-icon.success {\n\t\tcolor: #10b981;\n\t}\n\t\n\t.modal-title {\n\t\tfont-size: 20px;\n\t\tfont-weight: 700;\n\t\tmargin: 0 0 16px 0;\n\t\ttext-align: center;\n\t\tcolor: #111827;\n\t}\n\t\n\t.modal-message {\n\t\twhite-space: pre-line;\n\t\ttext-align: left;\n\t}\n\n\t\/* Custom checkboxes *\/\n\t.consent-checkbox {\n\t\tdisplay: flex;\n\t\talign-items: flex-start;\n\t\tgap: 12px;\n\t\tcursor: pointer;\n\t\tpadding: 14px 16px;\n\t\tborder-radius: 10px;\n\t\tborder: 1px solid #e5e7eb;\n\t\ttransition: border-color 0.15s, background-color 0.15s;\n\t}\n\n\t.consent-checkbox:hover {\n\t\tborder-color: #10b981;\n\t\tbackground-color: #f9fafb;\n\t}\n\n\t.consent-checkbox input[type=\"checkbox\"] {\n\t\tposition: absolute;\n\t\topacity: 0;\n\t\twidth: 22px;\n\t\theight: 22px;\n\t\tcursor: pointer;\n\t}\n\n\t.consent-check {\n\t\tflex-shrink: 0;\n\t\twidth: 22px;\n\t\theight: 22px;\n\t\tborder: 2px solid #9ca3af;\n\t\tborder-radius: 5px;\n\t\tmargin-top: 1px;\n\t\ttransition: all 0.15s;\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\t}\n\n\t.consent-check svg {\n\t\twidth: 14px;\n\t\theight: 14px;\n\t\topacity: 0;\n\t\ttransform: scale(0.5);\n\t\ttransition: all 0.15s;\n\t}\n\n\t.consent-checkbox input[type=\"checkbox\"]:checked ~ .consent-check {\n\t\tbackground-color: #10b981;\n\t\tborder-color: #10b981;\n\t}\n\n\t.consent-checkbox input[type=\"checkbox\"]:checked ~ .consent-check svg {\n\t\topacity: 1;\n\t\ttransform: scale(1);\n\t}\n\n\t.consent-checkbox input[type=\"checkbox\"]:focus-visible ~ .consent-check {\n\t\tbox-shadow: 0 0 0 3px rgba(16, 185, 129, 0.3);\n\t}\n\n\t.consent-checkbox .consent-text {\n\t\tfont-size: 14px;\n\t\tline-height: 1.55;\n\t\tcolor: #374151;\n\t}\n\n\t.consent-checkbox.consent-error {\n\t\tborder-color: #ef4444;\n\t\tbackground-color: #fef2f2;\n\t}\n\n\t.consent-checkbox .consent-text a {\n\t\tcolor: #2563eb;\n\t\ttext-decoration: underline;\n\t\ttext-underline-offset: 2px;\n\t}\n\n\t.consent-checkbox .consent-text a:hover {\n\t\tcolor: #1d4ed8;\n\t}\n\n\t\/* File upload *\/\n\t.file-upload-zone {\n\t\tborder: 2px dashed #d1d5db;\n\t\tborder-radius: 10px;\n\t\tpadding: 20px;\n\t\ttext-align: center;\n\t\tcursor: pointer;\n\t\ttransition: border-color 0.15s, background-color 0.15s;\n\t}\n\n\t.file-upload-zone:hover,\n\t.file-upload-zone.dragover {\n\t\tborder-color: #10b981;\n\t\tbackground-color: #f0fdf4;\n\t}\n\n\t.file-upload-zone input[type=\"file\"] {\n\t\tdisplay: none !important;\n\t}\n\n\t\/* Single-file zones collapse once filled - the tile becomes the control. Multi-file\n\t   zones (data-multiple) never get this class, so more files can always be added. *\/\n\t.file-upload-zone--filled {\n\t\tdisplay: none;\n\t}\n\n\t.file-upload-browse {\n\t\tcolor: #10b981;\n\t\tfont-weight: 600;\n\t\tcursor: pointer;\n\t}\n\n\t.file-upload-browse:hover {\n\t\ttext-decoration: underline;\n\t}\n\n\t.file-upload-meta {\n\t\tmargin-top: 8px;\n\t\tfont-size: 12px;\n\t\tcolor: #9ca3af;\n\t\tline-height: 1.5;\n\t}\n\n\t.file-list {\n\t\tmargin-top: 10px;\n\t}\n\n\t.file-list-item {\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: space-between;\n\t\tpadding: 8px 12px;\n\t\tborder: 1px solid #e5e7eb;\n\t\tborder-radius: 8px;\n\t\tmargin-top: 6px;\n\t\tbackground-color: #fafafa;\n\t\ttransition: border-color 0.15s;\n\t}\n\n\t.file-list-item:hover {\n\t\tborder-color: #d1d5db;\n\t}\n\n\t.file-list-item-info {\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tgap: 8px;\n\t\tmin-width: 0;\n\t}\n\n\t.file-list-item-icon {\n\t\tflex-shrink: 0;\n\t\twidth: 28px;\n\t\theight: 28px;\n\t\tborder-radius: 6px;\n\t\tbackground-color: #f3f4f6;\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\t}\n\n\t.file-list-item-icon svg {\n\t\twidth: 14px;\n\t\theight: 14px;\n\t\tcolor: #6b7280;\n\t}\n\n\t.file-list-item-name {\n\t\tfont-size: 13px;\n\t\tfont-weight: 500;\n\t\tcolor: #374151;\n\t\twhite-space: nowrap;\n\t\toverflow: hidden;\n\t\ttext-overflow: ellipsis;\n\t}\n\n\t.file-list-item-size {\n\t\tfont-size: 11px;\n\t\tcolor: #9ca3af;\n\t\tflex-shrink: 0;\n\t\tmargin-left: 4px;\n\t}\n\n\t.file-list-item-remove {\n\t\tflex-shrink: 0;\n\t\twidth: 24px;\n\t\theight: 24px;\n\t\tborder: none;\n\t\tbackground: none;\n\t\tcursor: pointer;\n\t\tborder-radius: 4px;\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\t\tcolor: #9ca3af;\n\t\ttransition: all 0.15s;\n\t\tmargin-left: 8px;\n\t}\n\n\t.file-list-item-remove:hover {\n\t\tbackground-color: #fef2f2;\n\t\tcolor: #ef4444;\n\t}\n\n\t.file-list-item-remove svg {\n\t\twidth: 14px;\n\t\theight: 14px;\n\t}\n\n\t\/* Faktury i dokumentacja medyczna le\u017c\u0105 jedna pod drug\u0105 w tym samym \u015bwiadczeniu, a strefa\n\t   faktury znika po wype\u0142nieniu \u2014 bez rozr\u00f3\u017cnienia kolorem kafelki obu p\u00f3l zlewaj\u0105 si\u0119\n\t   w jedn\u0105 list\u0119 i nie wida\u0107, kt\u00f3ry plik nale\u017cy do kt\u00f3rego pola.\n\t   Faktura = zielony (dow\u00f3d kosztu, wymagany), dokumentacja = niebieski (materia\u0142\n\t   uzupe\u0142niaj\u0105cy). Kolor jest dodatkiem do etykiety, nie jedynym no\u015bnikiem znaczenia. *\/\n\t.file-list[data-list-role=\"invoice\"] .file-list-item {\n\t\tborder-left: 3px solid #10b981;\n\t}\n\n\t.file-list[data-list-role=\"invoice\"] .file-list-item-icon {\n\t\tbackground-color: #ecfdf5;\n\t}\n\n\t.file-list[data-list-role=\"invoice\"] .file-list-item-icon svg {\n\t\tcolor: #059669;\n\t}\n\n\t.file-list[data-list-role=\"medical\"] .file-list-item {\n\t\tborder-left: 3px solid #6366f1;\n\t}\n\n\t.file-list[data-list-role=\"medical\"] .file-list-item-icon {\n\t\tbackground-color: #eef2ff;\n\t}\n\n\t.file-list[data-list-role=\"medical\"] .file-list-item-icon svg {\n\t\tcolor: #4f46e5;\n\t}\n\n\t.file-upload-zone[data-zone-role=\"medical\"]:hover,\n\t.file-upload-zone[data-zone-role=\"medical\"].dragover {\n\t\tborder-color: #6366f1;\n\t\tbackground-color: #f5f3ff;\n\t}\n\n\t.file-upload-zone[data-zone-role=\"medical\"] .file-upload-browse {\n\t\tcolor: #4f46e5;\n\t}\n\n\t.confirm-modal-body {\n\t\tpadding: 28px 28px 20px;\n\t}\n\n\t.confirm-modal-body h3 {\n\t\tfont-size: 18px;\n\t\tfont-weight: 700;\n\t\tcolor: #111827;\n\t\tmargin: 0 0 16px 0;\n\t}\n\n\t.confirm-modal-body p {\n\t\tfont-size: 14px;\n\t\tline-height: 1.65;\n\t\tcolor: #4b5563;\n\t\tmargin: 0 0 14px 0;\n\t}\n\n\t.confirm-modal-note {\n\t\tpadding: 16px 18px;\n\t\tborder-radius: 10px;\n\t\tmargin-top: 12px;\n\t}\n\n\t.confirm-modal-note p {\n\t\tfont-size: 13px;\n\t\tmargin: 0;\n\t\tline-height: 1.6;\n\t}\n\n\t.confirm-modal-note .confirm-note-title {\n\t\tfont-size: 14px;\n\t\tfont-weight: 700;\n\t\tmargin-bottom: 6px;\n\t}\n\n\t.confirm-modal-note--warn {\n\t\tbackground-color: #fef3ed;\n\t\tborder: 1px solid #f5d0b5;\n\t}\n\n\t.confirm-modal-note--warn p {\n\t\tcolor: #9a3412;\n\t}\n\n\t.confirm-modal-note--danger {\n\t\tbackground-color: #fef2f2;\n\t\tborder: 1px solid #fecaca;\n\t}\n\n\t.confirm-modal-note--danger p {\n\t\tcolor: #991b1b;\n\t}\n\n\t.confirm-modal-footer {\n\t\tpadding: 0 28px 24px;\n\t\tdisplay: flex;\n\t\tgap: 10px;\n\t\tjustify-content: flex-end;\n\t}\n\n\t.confirm-btn {\n\t\tpadding: 10px 20px;\n\t\tborder-radius: 6px;\n\t\tcursor: pointer;\n\t\tfont-weight: 700;\n\t\tfont-size: 14px;\n\t\ttransition: all 0.15s;\n\t\tborder: none;\n\t}\n\n\t.confirm-btn-back {\n\t\tbackground-color: white;\n\t\tborder: 1px solid #d1d5db;\n\t\tcolor: #374151;\n\t}\n\n\t.confirm-btn-back:hover {\n\t\tbackground-color: #f3f4f6;\n\t\tborder-color: #9ca3af;\n\t}\n\n\t.remove-service.confirm-btn-back:hover {\n\t\tbackground-color: #fef2f2;\n\t\tborder-color: #f87171;\n\t}\n\n\t.confirm-btn-submit {\n\t\tbackground-color: #10b981;\n\t\tcolor: white;\n\t}\n\n\t.confirm-btn-submit:hover {\n\t\tbackground-color: #059669;\n\t}\n\n\t.confirm-btn-danger {\n\t\tbackground-color: #dc2626;\n\t\tcolor: white;\n\t}\n\n\t.confirm-btn-danger:hover {\n\t\tbackground-color: #b91c1c;\n\t}\n\n\t.warning-box {\n\t\tbackground-color: #fef3ed;\n\t\tborder: 1px solid #f5d0b5;\n\t}\n\n\t.warning-box-text {\n\t\tcolor: #9a3412;\n\t}\n\n\t.info-box {\n\t\tbackground-color: #fef2f2;\n\t\tborder: 1px solid #fecaca;\n\t}\n\n\t.info-box-text {\n\t\tcolor: #b91c1c;\n\t}\n\n\t.info-box-link {\n\t\tdisplay: inline-flex;\n\t\talign-items: center;\n\t\tgap: 6px;\n\t\tmargin-top: 8px;\n\t\tpadding: 6px 12px;\n\t\tbackground-color: #dc2626;\n\t\tcolor: #ffffff;\n\t\tborder-radius: 6px;\n\t\tfont-size: 0.875rem;\n\t\tfont-weight: 600;\n\t\ttext-decoration: none;\n\t}\n\n\t.info-box-link:hover {\n\t\tbackground-color: #b91c1c;\n\t}\n\n\t.field-info-hint {\n\t\tfont-size: 0.8125rem;\n\t\tcolor: #1f6f4a;\n\t\tmargin-top: 4px;\n\t}\n\n\t.remove-service-btn {\n\t\tborder-color: #fca5a5;\n\t\tcolor: #dc2626;\n\t}\n\n\t.remove-service-btn--hidden {\n\t\tdisplay: none;\n\t}\n\n\t\/* Unavailable page *\/\n\t.unavailable-page {\n\t\tdisplay: none;\n\t\tmin-height: 100vh;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\t\tpadding: 32px 20px;\n\t\tbackground: linear-gradient(160deg, #f0f4f8 0%, #e2e8f0 100%);\n\t}\n\n\t.unavailable-page.show {\n\t\tdisplay: flex;\n\t}\n\n\t.unavailable-card {\n\t\ttext-align: center;\n\t\tmax-width: 440px;\n\t\twidth: 100%;\n\t\tbackground: white;\n\t\tborder-radius: 16px;\n\t\tpadding: 48px 36px;\n\t\tbox-shadow:\n\t\t\t0 1px 3px rgba(0,0,0,0.04),\n\t\t\t0 8px 24px rgba(0,0,0,0.06);\n\t}\n\n\t.unavailable-icon {\n\t\twidth: 72px;\n\t\theight: 72px;\n\t\tmargin: 0 auto 28px;\n\t\tborder-radius: 50%;\n\t\tbackground: #fef3ed;\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\t}\n\n\t.unavailable-icon svg {\n\t\twidth: 32px;\n\t\theight: 32px;\n\t\tcolor: #ea580c;\n\t}\n\n\t.unavailable-page-title {\n\t\tfont-size: 24px;\n\t\tfont-weight: 700;\n\t\tcolor: #111827;\n\t\tmargin: 0 0 20px;\n\t\tline-height: 1.3;\n\t\ttext-align: center;\n\t}\n\n\t.unavailable-card h2 {\n\t\tfont-size: 22px;\n\t\tfont-weight: 700;\n\t\tcolor: #111827;\n\t\tmargin: 0 0 12px;\n\t\tline-height: 1.3;\n\t}\n\n\t.unavailable-card p {\n\t\tfont-size: 15px;\n\t\tline-height: 1.65;\n\t\tcolor: #6b7280;\n\t\tmargin: 0;\n\t}\n\n\t.unavailable-divider {\n\t\twidth: 40px;\n\t\theight: 3px;\n\t\tborder-radius: 2px;\n\t\tbackground: #d1d5db;\n\t\tmargin: 24px auto;\n\t}\n\n\t.unavailable-card .unavailable-hint {\n\t\tfont-size: 13px;\n\t\tcolor: #9ca3af;\n\t}\n\n\t@media (max-width: 640px) {\n\t\t.confirm-modal-footer {\n\t\t\tflex-direction: column-reverse;\n\t\t\tpadding: 0 20px 20px;\n\t\t}\n\n\t\t.confirm-modal-footer button {\n\t\t\twidth: 100%;\n\t\t\ttext-align: center;\n\t\t}\n\n\t\t.confirm-modal-body {\n\t\t\tpadding: 20px 20px 16px;\n\t\t}\n\t}\n\n\t\/* Section cards *\/\n\t.form-section {\n\t\tbackground-color: #ffffff;\n\t\tborder: 1px solid #e5e7eb;\n\t\tborder-radius: 12px;\n\t\tpadding: 24px;\n\t\tmargin-bottom: 20px;\n\t\tbox-shadow: 0 1px 3px rgba(0, 0, 0, 0.04), 0 1px 2px rgba(0, 0, 0, 0.03);\n\t}\n\n\t.form-section-title {\n\t\tfont-size: 17px;\n\t\tfont-weight: 700;\n\t\tcolor: #111827;\n\t\tmargin: 0 0 16px 0;\n\t}\n\n\t.form-section-title.has-subtitle {\n\t\tmargin-bottom: 4px;\n\t}\n\n\t.form-section-subtitle {\n\t\tfont-size: 14px;\n\t\tfont-weight: 400;\n\t\tcolor: #6b7280;\n\t\tmargin: 0 0 16px 0;\n\t}\n\n\t.form-subsection-title {\n\t\tfont-size: 15px;\n\t\tfont-weight: 600;\n\t\tcolor: #374151;\n\t\tmargin: 8px 0 12px 0;\n\t}\n\n\t.form-grid-2 {\n\t\tdisplay: grid;\n\t\tgrid-template-columns: repeat(2, minmax(0, 1fr));\n\t\tgap: 12px 20px;\n\t\tmargin-bottom: 16px;\n\t}\n\n\t.form-grid-2 > .form-grid-2-full {\n\t\tgrid-column: 1 \/ -1;\n\t}\n\n\t.form-grid-2-inner {\n\t\tdisplay: grid;\n\t\tgrid-template-columns: repeat(2, minmax(0, 1fr));\n\t\tgap: 12px;\n\t}\n\n\t@media (max-width: 640px) {\n\t\t.form-grid-2,\n\t\t.form-grid-2-inner {\n\t\t\tgrid-template-columns: 1fr;\n\t\t\tgap: 12px;\n\t\t}\n\n\t\t.form-section {\n\t\t\tpadding: 18px;\n\t\t}\n\t}\n\n\t\/* Service subsection (each \u015bwiadczenie) *\/\n\t.service-subsection {\n\t\tborder: 1px dashed #d1d5db;\n\t\tborder-radius: 10px;\n\t\tpadding: 20px;\n\t\tmargin-bottom: 16px;\n\t\tbackground-color: #fafafa;\n\t}\n\n\t.service-subsection-header {\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: space-between;\n\t\tmargin-bottom: 12px;\n\t\tgap: 12px;\n\t}\n\n\t.service-subsection-title {\n\t\tfont-size: 13px;\n\t\tfont-weight: 700;\n\t\tcolor: #6b7280;\n\t\ttext-transform: uppercase;\n\t\tletter-spacing: 0.04em;\n\t\tmargin: 0;\n\t}\n\n\t@media (max-width: 640px) {\n\t\t.service-subsection {\n\t\t\tpadding: 16px;\n\t\t}\n\t}\n\n\t\/* Weryfikacja wniosku panel *\/\n\t.issues-panel {\n\t\tposition: fixed;\n\t\tright: 1.5rem;\n\t\tbottom: 1.5rem;\n\t\twidth: 24rem;\n\t\tmax-width: calc(100vw - 2rem);\n\t\tbackground-color: #ffffff;\n\t\tborder: 1px solid #e5e7eb;\n\t\tborder-radius: 12px;\n\t\tbox-shadow: 0 10px 25px rgba(0, 0, 0, 0.08), 0 4px 10px rgba(0, 0, 0, 0.04);\n\t\tz-index: 50;\n\t\toverflow: hidden;\n\t\tdisplay: none;\n\t\tflex-direction: column;\n\t}\n\n\t.issues-panel.is-visible {\n\t\tdisplay: flex;\n\t}\n\n\t.issues-panel-header {\n\t\tpadding: 16px 18px;\n\t\tborder-bottom: 1px solid #f3f4f6;\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tgap: 10px;\n\t}\n\n\t.issues-panel-header-icon {\n\t\tflex-shrink: 0;\n\t\twidth: 28px;\n\t\theight: 28px;\n\t\tborder-radius: 50%;\n\t\tbackground-color: #ecfdf5;\n\t\tcolor: #059669;\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\t}\n\n\t.issues-panel-header-icon svg {\n\t\twidth: 16px;\n\t\theight: 16px;\n\t}\n\n\t.issues-panel-header-title {\n\t\tflex: 1;\n\t\tfont-size: 15px;\n\t\tfont-weight: 700;\n\t\tcolor: #111827;\n\t\tmargin: 0;\n\t}\n\n\t.issues-panel-close {\n\t\tflex-shrink: 0;\n\t\twidth: 28px;\n\t\theight: 28px;\n\t\tborder: none;\n\t\tbackground: none;\n\t\tcursor: pointer;\n\t\tborder-radius: 6px;\n\t\tcolor: #6b7280;\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\t\tfont-size: 18px;\n\t\tline-height: 1;\n\t\ttransition: background-color 0.15s, color 0.15s;\n\t}\n\n\t.issues-panel-close:hover {\n\t\tbackground-color: #f3f4f6;\n\t\tcolor: #111827;\n\t}\n\n\t.issues-panel-chips {\n\t\tpadding: 12px 18px 0 18px;\n\t\tdisplay: flex;\n\t\tgap: 8px;\n\t\tflex-wrap: wrap;\n\t}\n\n\t.issues-chip {\n\t\tdisplay: inline-flex;\n\t\talign-items: center;\n\t\tpadding: 4px 10px;\n\t\tborder-radius: 999px;\n\t\tfont-size: 12px;\n\t\tfont-weight: 700;\n\t}\n\n\t.issues-chip--error {\n\t\tbackground-color: #ef4444;\n\t\tcolor: #ffffff;\n\t}\n\n\t.issues-chip--warning {\n\t\tbackground-color: #f59e0b;\n\t\tcolor: #ffffff;\n\t}\n\n\t.issues-chip--success {\n\t\tbackground-color: #16a34a;\n\t\tcolor: #ffffff;\n\t}\n\n\t.issues-chip--info {\n\t\tbackground-color: #2563eb;\n\t\tcolor: #ffffff;\n\t}\n\n\t.issues-chip.is-hidden {\n\t\tdisplay: none;\n\t}\n\n\t.issues-panel-body {\n\t\tpadding: 12px 18px 18px 18px;\n\t\toverflow-y: auto;\n\t\tmax-height: 60vh;\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tgap: 10px;\n\t}\n\n\t.issues-entry {\n\t\tborder: 1px solid #e5e7eb;\n\t\tborder-radius: 10px;\n\t\tpadding: 12px 14px;\n\t\tbackground-color: #ffffff;\n\t\ttransition: opacity 0.15s, border-color 0.15s, background-color 0.15s;\n\t\topacity: 1;\n\t}\n\n\t.issues-entry.is-entering {\n\t\topacity: 0;\n\t}\n\n\t.issues-entry-row {\n\t\tdisplay: flex;\n\t\tgap: 10px;\n\t\talign-items: flex-start;\n\t}\n\n\t.issues-entry-icon {\n\t\tflex-shrink: 0;\n\t\twidth: 20px;\n\t\theight: 20px;\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\t\tmargin-top: 1px;\n\t}\n\n\t.issues-entry-icon svg {\n\t\twidth: 18px;\n\t\theight: 18px;\n\t}\n\n\t.issues-entry-content {\n\t\tflex: 1;\n\t\tmin-width: 0;\n\t}\n\n\t.issues-entry-title {\n\t\tfont-size: 14px;\n\t\tfont-weight: 600;\n\t\tcolor: #111827;\n\t\tline-height: 1.45;\n\t\tmargin: 0;\n\t}\n\n\t.issues-entry-section {\n\t\tmargin-top: 4px;\n\t\tfont-size: 12px;\n\t\tcolor: #6b7280;\n\t}\n\n\t.issues-entry-footnote {\n\t\tmargin-top: 4px;\n\t\tfont-size: 12px;\n\t\tfont-weight: 600;\n\t}\n\n\t.issues-entry-action {\n\t\tmargin-top: 10px;\n\t\tdisplay: inline-flex;\n\t\talign-items: center;\n\t\tgap: 6px;\n\t\tpadding: 6px 12px;\n\t\tbackground-color: #ffffff;\n\t\tborder: 1px solid #e5e7eb;\n\t\tborder-radius: 8px;\n\t\tfont-size: 13px;\n\t\tfont-weight: 600;\n\t\tcolor: #374151;\n\t\tcursor: pointer;\n\t\ttransition: border-color 0.15s, background-color 0.15s;\n\t}\n\n\t.issues-entry-action:hover {\n\t\tborder-color: #9ca3af;\n\t\tbackground-color: #f9fafb;\n\t}\n\n\t.issues-entry-action svg {\n\t\twidth: 12px;\n\t\theight: 12px;\n\t}\n\n\t.issues-entry-close {\n\t\tflex-shrink: 0;\n\t\twidth: 24px;\n\t\theight: 24px;\n\t\tdisplay: inline-flex;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\t\tpadding: 0;\n\t\tmargin: -2px -4px 0 0;\n\t\tbackground: transparent;\n\t\tborder: 0;\n\t\tborder-radius: 6px;\n\t\tcolor: #6b7280;\n\t\tcursor: pointer;\n\t\ttransition: background-color 0.15s, color 0.15s;\n\t}\n\n\t.issues-entry-close:hover {\n\t\tbackground-color: rgba(0, 0, 0, 0.06);\n\t\tcolor: #111827;\n\t}\n\n\t.issues-entry-close svg {\n\t\twidth: 14px;\n\t\theight: 14px;\n\t}\n\n\t.issues-entry--error {\n\t\tborder-color: #fecaca;\n\t\tbackground-color: #fef2f2;\n\t}\n\n\t.issues-entry--error .issues-entry-icon {\n\t\tcolor: #dc2626;\n\t}\n\n\t.issues-entry--error .issues-entry-footnote {\n\t\tcolor: #b91c1c;\n\t}\n\n\t.issues-entry--warning {\n\t\tborder-color: #fcd9a3;\n\t\tbackground-color: #fffbeb;\n\t}\n\n\t.issues-entry--warning .issues-entry-icon {\n\t\tcolor: #d97706;\n\t}\n\n\t.issues-entry--info {\n\t\tborder-color: #93c5fd;\n\t\tbackground-color: #eff6ff;\n\t}\n\n\t.issues-entry--info .issues-entry-icon {\n\t\tcolor: #2563eb;\n\t}\n\n\t.issues-entry--success {\n\t\tborder-color: #bbf7d0;\n\t\tbackground-color: #f0fdf4;\n\t}\n\n\t.issues-entry--success .issues-entry-icon {\n\t\tcolor: #059669;\n\t}\n\n\t.issues-badge {\n\t\tposition: fixed;\n\t\tright: 1.5rem;\n\t\tbottom: 1.5rem;\n\t\tdisplay: none;\n\t\talign-items: center;\n\t\tgap: 8px;\n\t\tpadding: 10px 16px;\n\t\tbackground-color: #ffffff;\n\t\tborder: 1px solid #e5e7eb;\n\t\tborder-radius: 999px;\n\t\tbox-shadow: 0 4px 10px rgba(0, 0, 0, 0.06);\n\t\tcursor: pointer;\n\t\tfont-size: 13px;\n\t\tfont-weight: 700;\n\t\tcolor: #111827;\n\t\tz-index: 50;\n\t\ttransition: border-color 0.15s, background-color 0.15s;\n\t}\n\n\t.issues-badge.is-visible {\n\t\tdisplay: inline-flex;\n\t}\n\n\t.issues-badge:hover {\n\t\tborder-color: #9ca3af;\n\t\tbackground-color: #f9fafb;\n\t}\n\n\t.issues-badge-dot {\n\t\twidth: 8px;\n\t\theight: 8px;\n\t\tborder-radius: 50%;\n\t\tbackground-color: #ef4444;\n\t}\n\n\t.issues-badge-dot--warning {\n\t\tbackground-color: #f59e0b;\n\t}\n\n\t.issues-badge-dot--info {\n\t\tbackground-color: #2563eb;\n\t}\n\n\t.issues-badge-dot--success {\n\t\tbackground-color: #16a34a;\n\t}\n\n\t.issues-success-pill {\n\t\tposition: fixed;\n\t\tright: 1.5rem;\n\t\tbottom: 1.5rem;\n\t\tdisplay: none;\n\t\talign-items: center;\n\t\tgap: 8px;\n\t\tpadding: 10px 16px;\n\t\tbackground-color: #ecfdf5;\n\t\tborder: 1px solid #bbf7d0;\n\t\tborder-radius: 999px;\n\t\tbox-shadow: 0 4px 10px rgba(5, 150, 105, 0.10);\n\t\tfont-size: 13px;\n\t\tfont-weight: 700;\n\t\tcolor: #065f46;\n\t\tz-index: 50;\n\t}\n\n\t.issues-success-pill.is-visible {\n\t\tdisplay: inline-flex;\n\t}\n\n\t.issues-success-pill svg {\n\t\twidth: 16px;\n\t\theight: 16px;\n\t\tcolor: #059669;\n\t}\n\n\t@keyframes fieldPulse {\n\t\t0% { box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.55); }\n\t\t70% { box-shadow: 0 0 0 8px rgba(16, 185, 129, 0); }\n\t\t100% { box-shadow: 0 0 0 0 rgba(16, 185, 129, 0); }\n\t}\n\n\t.field-pulse {\n\t\tanimation: fieldPulse 1s ease-out 1;\n\t\tborder-color: #10b981 !important;\n\t}\n\n\t.issues-panel-toggle-all {\n\t\tdisplay: none;\n\t\twidth: 100%;\n\t\tpadding: 12px 18px;\n\t\tborder: none;\n\t\tborder-top: 1px solid #f3f4f6;\n\t\tbackground-color: #fafafa;\n\t\tfont-size: 13px;\n\t\tfont-weight: 700;\n\t\tcolor: #374151;\n\t\tcursor: pointer;\n\t\ttransition: background-color 0.15s;\n\t}\n\n\t.issues-panel-toggle-all:hover {\n\t\tbackground-color: #f3f4f6;\n\t}\n\n\t@media (max-width: 767px) {\n\t\t.issues-panel {\n\t\t\tright: 0.75rem;\n\t\t\tleft: 0.75rem;\n\t\t\tbottom: 0.75rem;\n\t\t\twidth: auto;\n\t\t\tmax-width: none;\n\t\t}\n\n\t\t.issues-panel-body {\n\t\t\tmax-height: 60vh;\n\t\t}\n\n\t\t.issues-badge,\n\t\t.issues-success-pill {\n\t\t\tright: 0.75rem;\n\t\t\tbottom: 0.75rem;\n\t\t}\n\n\t\t\/* Na mobile, gdy s\u0105 2+ wpisy, pokazujemy przycisk \"Poka\u017c wszystkie\" i ukrywamy reszt\u0119 *\/\n\t\t.issues-panel.has-multiple .issues-panel-toggle-all {\n\t\t\tdisplay: block;\n\t\t}\n\n\t\t.issues-panel.has-multiple.mobile-collapsed .issues-panel-body {\n\t\t\tmax-height: none;\n\t\t\toverflow-y: hidden;\n\t\t}\n\n\t\t.issues-panel.has-multiple.mobile-collapsed .issues-entry:not(:first-child) {\n\t\t\tdisplay: none;\n\t\t}\n\t}\n\n\t\/* \u2500\u2500 Stepper \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n\n\t.stepper {\n\t\tdisplay: flex;\n\t\talign-items: flex-start;\n\t\tmargin-bottom: 24px;\n\t\tpadding: 0;\n\t\tlist-style: none;\n\t}\n\n\t.stepper-step {\n\t\tflex: 1;\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\talign-items: center;\n\t\ttext-align: center;\n\t\tposition: relative;\n\t}\n\n\t.stepper-step:not(:last-child)::after {\n\t\tcontent: \"\";\n\t\tposition: absolute;\n\t\ttop: 16px;\n\t\tleft: 50%;\n\t\twidth: 100%;\n\t\theight: 2px;\n\t\tbackground: #e5e7eb;\n\t\tz-index: 0;\n\t}\n\n\t.stepper-step.is-complete:not(:last-child)::after {\n\t\tbackground: #10b981;\n\t}\n\n\t.stepper-badge {\n\t\twidth: 32px;\n\t\theight: 32px;\n\t\tborder-radius: 50%;\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\t\tfont-weight: 700;\n\t\tfont-size: 14px;\n\t\tbackground: #e5e7eb;\n\t\tcolor: #6b7280;\n\t\tposition: relative;\n\t\tz-index: 1;\n\t\ttransition: all .2s;\n\t}\n\n\t.stepper-step.is-active .stepper-badge {\n\t\tbackground: #10b981;\n\t\tcolor: #ffffff;\n\t\tbox-shadow: 0 0 0 4px #d1fae5;\n\t}\n\n\t.stepper-step.is-complete .stepper-badge {\n\t\tbackground: #10b981;\n\t\tcolor: #ffffff;\n\t}\n\n\t.stepper-label {\n\t\tmargin-top: 8px;\n\t\tfont-size: 13px;\n\t\tfont-weight: 600;\n\t\tcolor: #6b7280;\n\t}\n\n\t.stepper-step.is-active .stepper-label,\n\t.stepper-step.is-complete .stepper-label {\n\t\tcolor: #111827;\n\t}\n\n\t@media (max-width: 640px) {\n\t\t.stepper-label {\n\t\t\tfont-size: 11px;\n\t\t}\n\t}\n\n\t\/* Future steps stay out of the DOM flow entirely, so focus cannot reach them. *\/\n\t.wizard-step {\n\t\tdisplay: none;\n\t}\n\n\t.wizard-step.is-active {\n\t\tdisplay: block;\n\t}\n\n\t.wizard-step:focus {\n\t\toutline: none;\n\t}\n\n\t\/* Tailwind 2.2.19 is a static build: no arbitrary-value utilities like tracking-[0.5em]. *\/\n\t.otp-input {\n\t\tletter-spacing: 0.5em;\n\t\ttext-indent: 0.5em;\n\t\tfont-size: 1.25rem;\n\t\tfont-weight: 700;\n\t}\n\n\t.step-hint {\n\t\tfont-size: 13px;\n\t\tcolor: #6b7280;\n\t\tmargin-top: 6px;\n\t}\n\n\t.resend-btn:disabled {\n\t\topacity: 0.5;\n\t\tcursor: not-allowed;\n\t}\n\n\t\/* \u2500\u2500 Read-only claim summary (step 3) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n\n\t\/* These are facts, not fields. A bordered box on a tinted fill still reads as a\n\t   disabled <input>, so the box is gone: values sit unframed on one grouped panel,\n\t   and each section is labelled \"Tylko do odczytu\". Markup is <dl>\/<dt>\/<dd>. *\/\n\t.readonly-heading {\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: space-between;\n\t\tgap: 12px;\n\t\tflex-wrap: wrap;\n\t\tmargin-bottom: 16px;\n\t}\n\n\t.readonly-badge {\n\t\tdisplay: inline-flex;\n\t\talign-items: center;\n\t\tgap: 5px;\n\t\tflex-shrink: 0;\n\t\tpadding: 3px 9px;\n\t\tborder-radius: 999px;\n\t\tbackground-color: #f3f4f6;\n\t\tborder: 1px solid #e5e7eb;\n\t\tcolor: #6b7280;\n\t\tfont-size: 11px;\n\t\tfont-weight: 600;\n\t\ttext-transform: uppercase;\n\t\tletter-spacing: 0.04em;\n\t\twhite-space: nowrap;\n\t}\n\n\t.readonly-badge svg {\n\t\twidth: 11px;\n\t\theight: 11px;\n\t}\n\n\t\/* The badge row already carries the section's bottom margin. *\/\n\t.readonly-heading + .form-section-subtitle {\n\t\tmargin-top: -10px;\n\t}\n\n\t.readonly-grid {\n\t\tdisplay: grid;\n\t\tgrid-template-columns: repeat(2, minmax(0, 1fr));\n\t\tgap: 16px 28px;\n\t\tmargin: 0;\n\t\tpadding: 18px 20px;\n\t\tbackground-color: #f9fafb;\n\t\tborder: 1px solid #eef0f3;\n\t\tborder-radius: 10px;\n\t}\n\n\t.readonly-field--full {\n\t\tgrid-column: 1 \/ -1;\n\t}\n\n\t.readonly-label {\n\t\tdisplay: block;\n\t\tfont-size: 11px;\n\t\tfont-weight: 600;\n\t\ttext-transform: uppercase;\n\t\tletter-spacing: 0.05em;\n\t\tcolor: #9ca3af;\n\t\tmargin-bottom: 2px;\n\t}\n\n\t.readonly-value {\n\t\tdisplay: block;\n\t\tmargin: 0;\n\t\tpadding: 0;\n\t\tborder: 0;\n\t\tbackground: none;\n\t\tcolor: #1f2937;\n\t\tfont-size: 15px;\n\t\tfont-weight: 600;\n\t\tline-height: 1.45;\n\t\tword-break: break-word;\n\t}\n\n\t.readonly-value:empty::before {\n\t\tcontent: \"\u2014\";\n\t\tcolor: #d1d5db;\n\t\tfont-weight: 400;\n\t}\n\n\t@media (max-width: 640px) {\n\t\t.readonly-grid {\n\t\t\tgrid-template-columns: 1fr;\n\t\t\tgap: 14px;\n\t\t\tpadding: 16px;\n\t\t}\n\n\t\t.readonly-heading {\n\t\t\tmargin-bottom: 12px;\n\t\t}\n\t}\n\n\t\/* The warning box has no link variant upstream; the red .info-box-link would\n\t   clash with the amber palette. *\/\n\t.warning-box-link {\n\t\tdisplay: inline-flex;\n\t\talign-items: center;\n\t\tgap: 6px;\n\t\tmargin-top: 10px;\n\t\tpadding: 6px 12px;\n\t\tbackground-color: #c2410c;\n\t\tcolor: #ffffff;\n\t\tborder-radius: 6px;\n\t\tfont-size: 0.875rem;\n\t\tfont-weight: 600;\n\t\ttext-decoration: none;\n\t}\n\n\t.warning-box-link:hover {\n\t\tbackground-color: #9a3412;\n\t}\n\n<\/style>\n\n<script data-wp-block-html=\"js\">\n\/\/ Everything below runs only once the markup exists. WordPress renders the\n\/\/ block's JS field ABOVE its HTML field, so on WordPress this script parses\n\/\/ before a single form element is in the document \u2014 wiring listeners at parse\n\/\/ time throws on the first getElementById and kills the rest of the file.\n\/\/ Locally the order is the opposite, which is why that failure never shows up\n\/\/ offline. Same readyState pattern the two small scripts above already use.\nfunction initTopUpForm() {\n\t'use strict';\n\n\t\/\/ Steps that used to wait for DOMContentLoaded. This function already runs\n\t\/\/ after the DOM is ready, so that event would never fire again \u2014 but they\n\t\/\/ still must not run in place: several of them reach for consts declared\n\t\/\/ further down and would hit the temporal dead zone. The queue preserves the\n\t\/\/ original \"run once the whole file has been processed\" semantics.\n\tconst deferredSetup = [];\n\n\tfunction afterSetup(fn) {\n\t\tdeferredSetup.push(fn);\n\t}\n\n\tconst CLAIM_CHECK_ENDPOINT = '\/api\/public\/refund\/claim\/check';\n\tconst OTP_VERIFY_ENDPOINT = '\/api\/public\/refund\/returning-request\/otp\/verify';\n\tconst DRAFT_ENDPOINT = '\/api\/public\/refund\/returning-request\/draft';\n\tconst SUBMIT_ENDPOINT = '\/api\/public\/refund\/returning-request\/submit';\n\t\/\/ WordPress is the single source of truth for internal navigation. Read on\n\t\/\/ demand rather than into a const at parse time \u2014 WordPress decides where the\n\t\/\/ config script lands relative to this one, and a parse-time read could see\n\t\/\/ `undefined` and silently drop every link. Both return null when the admin\n\t\/\/ injected nothing; every consumer handles that instead of falling back to a\n\t\/\/ slug baked in here. \"New claim\" points at the form, never back at the\n\t\/\/ chooser \u2014 whoever clicks it has already chosen.\n\tfunction newClaimUrl() {\n\t\treturn window.TELEMEDI_REFUND_NEW_CLAIM_URL || null;\n\t}\n\n\tfunction successUrl() {\n\t\treturn window.TELEMEDI_REFUND_SUCCESS_URL || null;\n\t}\n\tconst CLAIM_NUMBER_RE = \/^\\d{12}(\\.\\d{3})?$\/;\n\tconst REQUEST_TIMEOUT_MS = 60000;\n\tconst RESEND_COOLDOWN_SECONDS = 60;\n\n\t\/\/ Cross-step handles established by the returning-request flow:\n\t\/\/   matchedIssueId \u2014 issue UUID from claim\/check's otpSent branch; keys the OTP verify call.\n\t\/\/   sessionToken   \u2014 short-lived bearer minted by verify; authorizes draft + submit.\n\t\/\/   lastClaim\/lastPesel \u2014 retained so \"wy\u015blij ponownie\" can re-issue the OTP via claim\/check.\n\tlet matchedIssueId = null;\n\tlet sessionToken = null;\n\tlet verifyInFlight = false;\n\tlet verifyGeneration = 0;\n\tlet lastClaim = '';\n\tlet lastPesel = '';\n\n\t\/\/ Every status maps to one of these. The problem+json `detail` from the server is\n\t\/\/ never surfaced: it can distinguish \"no such claim\" from \"wrong PESEL\", which the\n\t\/\/ endpoint deliberately collapses into a single {exists:false} (anti-enumeration).\n\tconst MSG = {\n\t\tnotFound: 'Nieodnaleziono wniosku. Wpisz poprawne dane lub za\u0142\u00f3\u017c nowy wniosek',\n\t\tnoPhone: 'Do tego wniosku nie jest przypisany numer telefonu, dlatego nie mo\u017cemy wys\u0142a\u0107 kodu potwierdzenia SMS. Skontaktuj si\u0119 z naszym dzia\u0142em obs\u0142ugi lub z\u0142\u00f3\u017c nowy wniosek.',\n\t\tdeliveryFailed: 'Nie uda\u0142o si\u0119 wys\u0142a\u0107 kodu SMS. Spr\u00f3buj ponownie za chwil\u0119 lub skontaktuj si\u0119 z obs\u0142ug\u0105.',\n\t\trateLimited: 'Zbyt wiele pr\u00f3b. Spr\u00f3buj ponownie za kilka minut.',\n\t\tinvalidInput: 'Sprawd\u017a poprawno\u015b\u0107 numeru wniosku i numeru PESEL.',\n\t\tnetwork: 'Wyst\u0105pi\u0142 problem z po\u0142\u0105czeniem. Spr\u00f3buj ponownie za chwil\u0119.',\n\t\totpInvalid: 'Nieprawid\u0142owy lub nieaktualny kod. Sprawd\u017a SMS i spr\u00f3buj ponownie.',\n\t\totpRateLimited: 'Zbyt wiele pr\u00f3b. Odczekaj chwil\u0119 przed kolejn\u0105 pr\u00f3b\u0105.',\n\t\tsessionExpired: 'Sesja wygas\u0142a. Zweryfikuj wniosek jeszcze raz.',\n\t\tsubmitError: 'Nie uda\u0142o si\u0119 wys\u0142a\u0107 wniosku. Spr\u00f3buj ponownie za chwil\u0119.'\n\t};\n\n\tconst wizardState = { current: 1, maxUnlocked: 1 };\n\tconst completedSteps = new Set();\n\n\tconst panels = Array.prototype.slice.call(document.querySelectorAll('.wizard-step'));\n\tconst stepperItems = Array.prototype.slice.call(document.querySelectorAll('.stepper-step'));\n\n\tconst form = document.getElementById('topUpForm');\n\tconst claimInput = document.getElementById('claimNumber');\n\tconst peselInput = document.getElementById('claimPesel');\n\tconst claimError = document.getElementById('claimNumberError');\n\tconst peselError = document.getElementById('claimPeselError');\n\tconst resultEl = document.getElementById('step1Result');\n\tconst checkBtn = document.getElementById('checkClaimBtn');\n\tconst checkLoader = document.getElementById('checkClaimLoader');\n\n\tconst otpInput = document.getElementById('otpCode');\n\tconst verifyBtn = document.getElementById('verifyOtpBtn');\n\tconst verifyLoader = document.getElementById('verifyOtpLoader');\n\tconst resendBtn = document.getElementById('resendOtpBtn');\n\tconst cooldownEl = document.getElementById('resendCooldown');\n\tconst otpErrorEl = document.getElementById('otpError');\n\tconst otpMaskedPhoneEl = document.getElementById('otpMaskedPhone');\n\n\t\/* \u2500\u2500 PESEL \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n\t\/\/ Copied verbatim from refundacje\/nowy-wniosek.html \u2014 this repo has no build system\n\t\/\/ and no shared JS, so duplication is the only option.\n\tfunction validatePESEL(pesel) {\n\t\t\/\/ Sprawd\u017a czy PESEL ma dok\u0142adnie 11 cyfr\n\t\tif (!\/^\\d{11}$\/.test(pesel)) {\n\t\t\treturn false;\n\t\t}\n\n\t\t\/\/ Wagi dla poszczeg\u00f3lnych cyfr PESEL\n\t\tconst weights = [1, 3, 7, 9, 1, 3, 7, 9, 1, 3, 1];\n\n\t\t\/\/ Obliczanie sumy kontrolnej\n\t\tlet sum = 0;\n\t\tfor (let i = 0; i < 11; i++) {\n\t\t\t\/\/> this comment is used to circumvent the https:\/\/core.trac.wordpress.org\/ticket\/43785 bug\n\t\t\tsum += parseInt(pesel.charAt(i)) * weights[i];\n\t\t}\n\n\t\t\/\/ Sprawdzenie sumy kontrolnej - ostatnia cyfra sumy musi by\u0107 0\n\t\treturn sum % 10 === 0;\n\t}\n\n\t\/* \u2500\u2500 Stepper \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n\n\tfunction updateStepper() {\n\t\tstepperItems.forEach(function (item) {\n\t\t\tconst step = Number(item.dataset.step);\n\t\t\titem.classList.remove('is-active', 'is-complete', 'is-locked');\n\t\t\titem.removeAttribute('aria-current');\n\n\t\t\tif (step === wizardState.current) {\n\t\t\t\titem.classList.add('is-active');\n\t\t\t\titem.setAttribute('aria-current', 'step');\n\t\t\t} else if (completedSteps.has(step)) {\n\t\t\t\titem.classList.add('is-complete');\n\t\t\t} else {\n\t\t\t\titem.classList.add('is-locked');\n\t\t\t}\n\t\t});\n\t}\n\n\tfunction goToStep(n) {\n\t\tif (wizardState.maxUnlocked >= n) {\n\t\t\twizardState.current = n;\n\t\t\tpanels.forEach(function (panel) {\n\t\t\t\tpanel.classList.toggle('is-active', Number(panel.dataset.step) === n);\n\t\t\t});\n\t\t\tupdateStepper();\n\n\t\t\t\/\/ Move focus into the newly revealed step so keyboard and screen-reader\n\t\t\t\/\/ users are not stranded on the previous one.\n\t\t\tconst active = document.getElementById('step' + n);\n\t\t\tif (active) {\n\t\t\t\tactive.focus();\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction unlockStep(n) {\n\t\tif (n > wizardState.maxUnlocked) {\n\t\t\twizardState.maxUnlocked = n;\n\t\t}\n\t}\n\n\t\/* \u2500\u2500 Komunikaty kroku 1 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n\n\tfunction clearResult() {\n\t\tresultEl.textContent = '';\n\t}\n\n\tfunction showBox(variant, message, linkLabel, linkHref) {\n\t\tclearResult();\n\n\t\tconst box = document.createElement('div');\n\t\tbox.className = 'px-4 py-3 rounded-lg ' + (variant === 'warning' ? 'warning-box' : 'info-box');\n\n\t\tconst text = document.createElement('p');\n\t\ttext.className = 'text-sm ' + (variant === 'warning' ? 'warning-box-text' : 'info-box-text');\n\t\ttext.textContent = message;\n\t\tbox.appendChild(text);\n\n\t\tif (linkLabel && linkHref) {\n\t\t\tconst link = document.createElement('a');\n\t\t\tlink.className = 'info-box-link';\n\t\t\tlink.href = linkHref;\n\t\t\tlink.textContent = linkLabel;\n\t\t\tbox.appendChild(link);\n\t\t}\n\n\t\tresultEl.appendChild(box);\n\t}\n\n\tfunction toggleFieldError(el, visible) {\n\t\tel.classList.toggle('hidden', !visible);\n\t}\n\n\tfunction setBusy(busy) {\n\t\tcheckBtn.disabled = busy;\n\t\tcheckBtn.setAttribute('aria-busy', busy ? 'true' : 'false');\n\t\tcheckLoader.classList.toggle('show', busy);\n\t}\n\n\t\/* \u2500\u2500 Krok 1: weryfikacja wniosku \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n\n\tfunction handleResponse(result) {\n\t\t\/\/ The claim-check limiter answers 403; the OTP-issue limiter behind it answers 429.\n\t\t\/\/ Both mean \"slow down\" \u2014 collapse them into one message (anti-enumeration).\n\t\tif (result.status === 403 || result.status === 429) {\n\t\t\tshowBox('info', MSG.rateLimited);\n\t\t\treturn;\n\t\t}\n\t\tif (result.status === 422 || result.status === 400) {\n\t\t\tshowBox('info', MSG.invalidInput);\n\t\t\treturn;\n\t\t}\n\t\tif (result.status !== 200 || !result.body) {\n\t\t\tshowBox('info', MSG.network);\n\t\t\treturn;\n\t\t}\n\n\t\tconst body = result.body;\n\n\t\t\/\/ {exists:false} covers both \"no such claim\" and \"PESEL mismatch\"; no further\n\t\t\/\/ detail is emitted. Do not widen that distinction.\n\t\tif (!body.exists) {\n\t\t\tshowBox('info', MSG.notFound, 'Nowy wniosek', newClaimUrl());\n\t\t\treturn;\n\t\t}\n\n\t\t\/\/ Claim matched but the OTP could not be dispatched. reason distinguishes a\n\t\t\/\/ permanent dead-end (no phone on file) from a transient delivery failure.\n\t\tif (!body.otpSent) {\n\t\t\tshowBox('warning', body.reason === 'delivery_failed' ? MSG.deliveryFailed : MSG.noPhone);\n\t\t\treturn;\n\t\t}\n\n\t\t\/\/ claim\/check has already sent the code. Carry the issue handle to the verify\n\t\t\/\/ step and open the resend window \u2014 do NOT re-issue here.\n\t\tmatchedIssueId = body.issueId || null;\n\t\tsetMaskedPhone(body.maskedPhone);\n\t\tsetOtpError('');\n\n\t\tcompletedSteps.add(1);\n\t\tunlockStep(2);\n\t\tgoToStep(2);\n\t\tstartResendCooldown(RESEND_COOLDOWN_SECONDS);\n\t}\n\n\tfunction submitCheck(claimNumber, pesel) {\n\t\t\/\/ Retained for the OTP resend, which re-runs claim\/check to issue a fresh code.\n\t\tlastClaim = claimNumber;\n\t\tlastPesel = pesel;\n\n\t\tconst controller = new AbortController();\n\t\tconst timeoutId = setTimeout(function () {\n\t\t\tcontroller.abort();\n\t\t}, REQUEST_TIMEOUT_MS);\n\n\t\tsetBusy(true);\n\t\tconst baseUrl = (window.TELEMEDI_API_BASE_URL || '').replace(\/\\\/+$\/, '');\n\n\t\tfetch(baseUrl + CLAIM_CHECK_ENDPOINT, {\n\t\t\tmethod: 'POST',\n\t\t\theaders: { 'Content-Type': 'application\/json', 'Accept': 'application\/json' },\n\t\t\tbody: JSON.stringify({ claimNumber: claimNumber, pesel: pesel }),\n\t\t\tsignal: controller.signal\n\t\t})\n\t\t\t.then(function (res) {\n\t\t\t\tif (res.status === 200) {\n\t\t\t\t\treturn res.json().then(function (body) {\n\t\t\t\t\t\treturn { status: 200, body: body };\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn { status: res.status, body: null };\n\t\t\t})\n\t\t\t.then(handleResponse)\n\t\t\t.catch(function () {\n\t\t\t\t\/\/ Abort, timeout, DNS, CORS \u2014 all indistinguishable to the user.\n\t\t\t\tshowBox('info', MSG.network);\n\t\t\t})\n\t\t\t.then(function () {\n\t\t\t\tclearTimeout(timeoutId);\n\t\t\t\tsetBusy(false);\n\t\t\t});\n\t}\n\n\tfunction handleStep1Submit() {\n\t\tclearResult();\n\n\t\tconst claimNumber = claimInput.value.trim().replace(\/\\s+\/g, '');\n\t\tconst pesel = peselInput.value.trim();\n\n\t\tconst claimOk = CLAIM_NUMBER_RE.test(claimNumber);\n\t\tconst peselOk = validatePESEL(pesel);\n\n\t\ttoggleFieldError(claimError, !claimOk);\n\t\ttoggleFieldError(peselError, !peselOk);\n\n\t\tif (claimOk && peselOk) {\n\t\t\tsubmitCheck(claimNumber, pesel);\n\t\t}\n\t}\n\n\t\/\/ Steps 1 and 3 share one <form>, so route the submit event by the active step.\n\t\/\/ Step 3's \"Wy\u015blij wniosek\" is type=\"submit\" (identical to the original form),\n\t\/\/ which would otherwise re-run the step-1 claim check.\n\tform.addEventListener('submit', function (event) {\n\t\tevent.preventDefault();\n\n\t\tif (wizardState.current === 1) {\n\t\t\thandleStep1Submit();\n\t\t} else if (wizardState.current === 3) {\n\t\t\thandleFinalSubmit();\n\t\t}\n\t});\n\n\t\/* \u2500\u2500 Krok 2: kod OTP (UI only) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n\n\tfunction renderCooldown(seconds) {\n\t\tcooldownEl.textContent = seconds ? '(' + seconds + ' s)' : '';\n\t}\n\n\tfunction startResendCooldown(seconds) {\n\t\tlet remaining = seconds;\n\t\tresendBtn.disabled = true;\n\t\trenderCooldown(remaining);\n\n\t\tconst timer = setInterval(function () {\n\t\t\tremaining -= 1;\n\t\t\tif (remaining > 0) {\n\t\t\t\trenderCooldown(remaining);\n\t\t\t} else {\n\t\t\t\tclearInterval(timer);\n\t\t\t\tresendBtn.disabled = false;\n\t\t\t\trenderCooldown(0);\n\t\t\t}\n\t\t}, 1000);\n\t}\n\n\tfunction setMaskedPhone(masked) {\n\t\tif (!otpMaskedPhoneEl) { return; }\n\t\totpMaskedPhoneEl.textContent = masked ? (' na numer ' + masked) : '';\n\t}\n\n\tfunction setOtpError(message) {\n\t\tif (!otpErrorEl) { return; }\n\t\totpErrorEl.textContent = message || '';\n\t\totpErrorEl.classList.toggle('hidden', !message);\n\t}\n\n\tfunction syncVerifyButton() {\n\t\tconst ready = otpInput.value.length === 6 && !verifyInFlight;\n\t\tverifyBtn.disabled = !ready;\n\t\tverifyBtn.classList.toggle('opacity-50', !ready);\n\t\tverifyBtn.classList.toggle('cursor-not-allowed', !ready);\n\t}\n\n\tfunction setVerifyBusy(busy) {\n\t\tverifyBtn.setAttribute('aria-busy', busy ? 'true' : 'false');\n\t\tif (verifyLoader) {\n\t\t\tverifyLoader.classList.toggle('show', busy);\n\t\t}\n\t\tsyncVerifyButton();\n\t}\n\n\t\/\/ Resend re-runs claim\/check, which issues a fresh SMS code and returns a new issueId\n\t\/\/ + maskedPhone. Separate from the initial check so it stays on step 2 and reports\n\t\/\/ failures inline rather than on the step-1 result box.\n\tfunction resendOtp() {\n\t\tif (!lastClaim || !lastPesel) {\n\t\t\treturn;\n\t\t}\n\t\tsetOtpError('');\n\t\tverifyGeneration += 1;\n\t\tresendBtn.disabled = true;\n\n\t\tconst baseUrl = (window.TELEMEDI_API_BASE_URL || '').replace(\/\\\/+$\/, '');\n\t\tfetch(baseUrl + CLAIM_CHECK_ENDPOINT, {\n\t\t\tmethod: 'POST',\n\t\t\theaders: { 'Content-Type': 'application\/json', 'Accept': 'application\/json' },\n\t\t\tbody: JSON.stringify({ claimNumber: lastClaim, pesel: lastPesel })\n\t\t})\n\t\t\t.then(function (res) {\n\t\t\t\tif (res.status === 200) {\n\t\t\t\t\treturn res.json().then(function (b) { return { status: 200, body: b }; });\n\t\t\t\t}\n\t\t\t\treturn { status: res.status, body: null };\n\t\t\t})\n\t\t\t.then(function (result) {\n\t\t\t\tif (result.status === 403 || result.status === 429) {\n\t\t\t\t\tsetOtpError(MSG.otpRateLimited);\n\t\t\t\t\tresendBtn.disabled = false;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (result.status === 200 && result.body && result.body.exists && result.body.otpSent) {\n\t\t\t\t\tmatchedIssueId = result.body.issueId || matchedIssueId;\n\t\t\t\t\tsetMaskedPhone(result.body.maskedPhone);\n\t\t\t\t\tstartResendCooldown(RESEND_COOLDOWN_SECONDS);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsetOtpError(MSG.deliveryFailed);\n\t\t\t\tresendBtn.disabled = false;\n\t\t\t})\n\t\t\t.catch(function () {\n\t\t\t\tsetOtpError(MSG.network);\n\t\t\t\tresendBtn.disabled = false;\n\t\t\t});\n\t}\n\n\t\/\/ Verify the code against the returning-request endpoint. Success mints the session\n\t\/\/ token used by the draft + submit steps; 400\/422 means the code was wrong or expired.\n\tfunction verifyOtp() {\n\t\tif (verifyInFlight) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst code = otpInput.value.trim();\n\t\tif (!\/^\\d{6}$\/.test(code)) {\n\t\t\treturn;\n\t\t}\n\t\tif (!matchedIssueId) {\n\t\t\tsetOtpError(MSG.sessionExpired);\n\t\t\treturn;\n\t\t}\n\n\t\tsetOtpError('');\n\t\tverifyInFlight = true;\n\t\tconst generation = ++verifyGeneration;\n\t\tsetVerifyBusy(true);\n\n\t\tconst baseUrl = (window.TELEMEDI_API_BASE_URL || '').replace(\/\\\/+$\/, '');\n\t\tfetch(baseUrl + OTP_VERIFY_ENDPOINT, {\n\t\t\tmethod: 'POST',\n\t\t\theaders: { 'Content-Type': 'application\/json', 'Accept': 'application\/json' },\n\t\t\tbody: JSON.stringify({ issueId: matchedIssueId, code: code })\n\t\t})\n\t\t\t.then(function (res) {\n\t\t\t\tif (res.status === 200) {\n\t\t\t\t\treturn res.json().then(function (b) { return { status: 200, body: b }; });\n\t\t\t\t}\n\t\t\t\treturn { status: res.status, body: null };\n\t\t\t})\n\t\t\t.then(function (result) {\n\t\t\t\tif (generation !== verifyGeneration) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (result.status === 429) {\n\t\t\t\t\tsetOtpError(MSG.otpRateLimited);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (result.status === 400 || result.status === 422) {\n\t\t\t\t\tsetOtpError(MSG.otpInvalid);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (result.status !== 200 || !result.body || !result.body.token) {\n\t\t\t\t\tsetOtpError(MSG.network);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tsessionToken = result.body.token;\n\t\t\t\tcompletedSteps.add(2);\n\t\t\t\tunlockStep(3);\n\t\t\t\tloadDraft();\n\t\t\t})\n\t\t\t.catch(function () {\n\t\t\t\tif (generation !== verifyGeneration) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsetOtpError(MSG.network);\n\t\t\t})\n\t\t\t.then(function () {\n\t\t\t\tverifyInFlight = false;\n\t\t\t\tsetVerifyBusy(false);\n\t\t\t});\n\t}\n\n\t\/\/ Fetch the read-only snapshot of the source claim to prefill step 3. The prefill is\n\t\/\/ convenience, not a gate: a non-401 failure still advances (with blanks) rather than\n\t\/\/ trapping a verified user. A 401 means the token is gone\/expired \u2014 restart from step 1.\n\tfunction loadDraft() {\n\t\tconst baseUrl = (window.TELEMEDI_API_BASE_URL || '').replace(\/\\\/+$\/, '');\n\t\tfetch(baseUrl + DRAFT_ENDPOINT, {\n\t\t\tmethod: 'GET',\n\t\t\theaders: { 'Accept': 'application\/json', 'Authorization': 'Bearer ' + sessionToken }\n\t\t})\n\t\t\t.then(function (res) {\n\t\t\t\tif (res.status === 200) {\n\t\t\t\t\treturn res.json().then(function (b) { return { status: 200, body: b }; });\n\t\t\t\t}\n\t\t\t\treturn { status: res.status, body: null };\n\t\t\t})\n\t\t\t.then(function (result) {\n\t\t\t\tif (result.status === 401) {\n\t\t\t\t\tsessionToken = null;\n\t\t\t\t\tgoToStep(1);\n\t\t\t\t\tshowBox('info', MSG.sessionExpired);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\trenderClaimSummary(result.body || {});\n\t\t\t\tgoToStep(3);\n\t\t\t})\n\t\t\t.catch(function () {\n\t\t\t\trenderClaimSummary({});\n\t\t\t\tgoToStep(3);\n\t\t\t});\n\t}\n\n\totpInput.addEventListener('input', function () {\n\t\tthis.value = this.value.replace(\/\\D\/g, '').slice(0, 6);\n\t\tsyncVerifyButton();\n\t\tsetOtpError('');\n\t});\n\n\tverifyBtn.addEventListener('click', verifyOtp);\n\tresendBtn.addEventListener('click', resendOtp);\n\n\n\t\/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\t   PORT ze `refundacje\/nowy-wniosek.html` \u2014 sekcja \"\u015awiadczenia zdrowotne\".\n\t   Skopiowane 1:1 (wraz z wci\u0119ciami), \u017ceby da\u0142o si\u0119 diffowa\u0107 z orygina\u0142em.\n\t   Brak build systemu => brak wsp\u00f3\u0142dzielonego JS. Poprawki w jednym pliku\n\t   trzeba nanie\u015b\u0107 tak\u017ce w drugim.\n\t   Pomini\u0119te: pipeline `refundVerify` (POST \/api\/refund\/verify) i\n\t   `revalidateFormIssues` \u2014 wszystkie wywo\u0142ania s\u0105 strze\u017cone `if (window.\u2026)`,\n\t   wi\u0119c same z siebie staj\u0105 si\u0119 no-opami.\n\t   \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 *\/\n\n\t\/* \u2500\u2500 Panel walidacji (formIssues) \u2014 RPWDL zapisuje tu swoje werdykty \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n\n    \/\/ Validation panel (\"Weryfikacja wniosku\")\n    const formIssues = (function () {\n        const entries = new Map();\n        let submitAttempted = false;\n        let collapsed = false;\n        let highestReachedSection = 0;\n        \/\/ True only once the user actually touches the form. Without this, a blank form would\n        \/\/ immediately show the green \"Wniosek wygl\u0105da dobrze\" success pill.\n        let hasInteracted = false;\n        \/\/ Mobile: by default only the top entry is visible, the rest sit behind a \"Poka\u017c wszystkie\" toggle.\n        let mobileExpanded = false;\n\n        const panelEl = document.getElementById('issuesPanel');\n        const bodyEl = document.getElementById('issuesPanelBody');\n        const chipErrorEl = document.getElementById('issuesChipError');\n        const chipWarningEl = document.getElementById('issuesChipWarning');\n        const chipSuccessEl = document.getElementById('issuesChipSuccess');\n        const chipInfoEl = document.getElementById('issuesChipInfo');\n        const closeBtn = document.getElementById('issuesPanelClose');\n        const badgeEl = document.getElementById('issuesBadge');\n        const badgeDotEl = document.getElementById('issuesBadgeDot');\n        const badgeTextEl = document.getElementById('issuesBadgeText');\n        const successPillEl = document.getElementById('issuesSuccessPill');\n        const toggleAllBtn = document.getElementById('issuesPanelToggleAll');\n        const toggleAllText = document.getElementById('issuesPanelToggleAllText');\n\n        function pluralPL(count, one, few, many) {\n            const abs = Math.abs(count);\n            if (abs === 1) return one;\n            const mod10 = abs % 10;\n            const mod100 = abs % 100;\n            if (mod10 >= 2 && 4 >= mod10  && (12 > mod100 || mod100 > 14)) return few;\n\t\t\t\/\/> this comment is used to circumvent the https:\/\/core.trac.wordpress.org\/ticket\/43785 bug\n            return many;\n        }\n\n        function errorsPlural(n) {\n            return `${n} ${pluralPL(n, 'b\u0142\u0105d', 'b\u0142\u0119dy', 'b\u0142\u0119d\u00f3w')}`;\n        }\n\n        function warningsPlural(n) {\n            return `${n} ${pluralPL(n, 'ostrze\u017cenie', 'ostrze\u017cenia', 'ostrze\u017ce\u0144')}`;\n        }\n\n        function successesPlural(n) {\n            return `${n} ${pluralPL(n, 'potwierdzenie', 'potwierdzenia', 'potwierdze\u0144')}`;\n        }\n\n        function infosPlural(n) {\n            return `${n} ${pluralPL(n, 'informacja', 'informacje', 'informacji')}`;\n        }\n\n        function severityIconSvg(severity) {\n            if (severity === 'error') {\n                return '<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"\/><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"13\"\/><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"\/><\/svg>';\n            }\n            if (severity === 'warning') {\n                return '<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\"\/><line x1=\"12\" y1=\"9\" x2=\"12\" y2=\"13\"\/><line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\"\/><\/svg>';\n            }\n            if (severity === 'success') {\n                return '<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M20 6 9 17l-5-5\"\/><\/svg>';\n            }\n            if (severity === 'info') {\n                return '<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"\/><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"\/><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"\/><\/svg>';\n            }\n            return '<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"\/><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"\/><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"\/><\/svg>';\n        }\n\n        function buildEntryEl(id, payload) {\n            const el = document.createElement('div');\n            el.className = `issues-entry issues-entry--${payload.severity}`;\n            el.dataset.issueId = id;\n            el.innerHTML = `\n                <div class=\"issues-entry-row\">\n                    <span class=\"issues-entry-icon\">${severityIconSvg(payload.severity)}<\/span>\n                    <div class=\"issues-entry-content\">\n                        <p class=\"issues-entry-title\"><\/p>\n                        <p class=\"issues-entry-section\" style=\"display:none;\"><\/p>\n                        <p class=\"issues-entry-footnote\" style=\"display:none;\">Trzeba poprawi\u0107 - bez tego nie wy\u015blesz wniosku.<\/p>\n                        <button type=\"button\" class=\"issues-entry-action\" style=\"display:none;\">\n                            <span class=\"issues-entry-action-label\">Przejd\u017a i popraw<\/span>\n                            <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"9 18 15 12 9 6\"\/><\/svg>\n                        <\/button>\n                    <\/div>\n                    <button type=\"button\" class=\"issues-entry-close\" aria-label=\"Zamknij\" style=\"display:none;\">\n                        <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"\/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"\/><\/svg>\n                    <\/button>\n                <\/div>\n            `;\n            applyPayload(el, payload);\n            return el;\n        }\n\n        function applyPayload(el, payload) {\n            const titleEl = el.querySelector('.issues-entry-title');\n            const sectionEl = el.querySelector('.issues-entry-section');\n            const footnoteEl = el.querySelector('.issues-entry-footnote');\n            const actionEl = el.querySelector('.issues-entry-action');\n            const actionLabelEl = el.querySelector('.issues-entry-action-label');\n            const closeEl = el.querySelector('.issues-entry-close');\n\n            if (titleEl.textContent !== payload.title) {\n                titleEl.textContent = payload.title;\n            }\n\n            if (payload.section) {\n                const text = `Sekcja: ${payload.section}`;\n                if (sectionEl.textContent !== text) sectionEl.textContent = text;\n                sectionEl.style.display = '';\n            } else {\n                sectionEl.style.display = 'none';\n            }\n\n            footnoteEl.style.display = payload.severity === 'error' ? '' : 'none';\n\n            const actionLabel = (payload.severity === 'success' || payload.severity === 'info') ? 'Przejd\u017a' : 'Przejd\u017a i popraw';\n            if (actionLabelEl && actionLabelEl.textContent !== actionLabel) {\n                actionLabelEl.textContent = actionLabel;\n            }\n\n            if (payload.fieldRef) {\n                actionEl.style.display = '';\n                actionEl.onclick = function () {\n                    goToField(payload.fieldRef);\n                };\n            } else {\n                actionEl.style.display = 'none';\n                actionEl.onclick = null;\n            }\n\n            if (closeEl) {\n                if (payload.severity === 'success' || payload.severity === 'info') {\n                    closeEl.style.display = '';\n                    closeEl.onclick = function () {\n                        if (typeof payload.onClose === 'function') payload.onClose();\n                        remove(el.dataset.issueId);\n                    };\n                } else {\n                    closeEl.style.display = 'none';\n                    closeEl.onclick = null;\n                }\n            }\n        }\n\n        function goToField(fieldRef) {\n            let el = typeof fieldRef === 'string' ? document.querySelector(fieldRef) : fieldRef;\n            if (!el) return;\n            \/\/ Ukryte inputy plik\u00f3w nie nadaj\u0105 si\u0119 do scrollu\/focus - przejd\u017a na opakowuj\u0105cy dropzone.\n            if (el.tagName === 'INPUT' && el.type === 'file') {\n                const zone = el.closest('.file-upload-zone');\n                if (zone) el = zone;\n            }\n            el.scrollIntoView({ behavior: 'smooth', block: 'center' });\n            try {\n                if (typeof el.focus === 'function') {\n                    el.focus({ preventScroll: true });\n                }\n            } catch (e) {\n                if (typeof el.focus === 'function') el.focus();\n            }\n            el.classList.remove('field-pulse');\n            void el.offsetWidth;\n            el.classList.add('field-pulse');\n            setTimeout(function () { el.classList.remove('field-pulse'); }, 1000);\n        }\n\n        function recomputeCounts() {\n            let errorCount = 0;\n            let warningCount = 0;\n            let successCount = 0;\n            let infoCount = 0;\n            entries.forEach(function (record) {\n                if (record.payload.severity === 'error') errorCount++;\n                else if (record.payload.severity === 'warning') warningCount++;\n                else if (record.payload.severity === 'success') successCount++;\n                else if (record.payload.severity === 'info') infoCount++;\n            });\n            return { errorCount: errorCount, warningCount: warningCount, successCount: successCount, infoCount: infoCount };\n        }\n\n        function render() {\n            const counts = recomputeCounts();\n\n            if (counts.errorCount > 0) {\n                chipErrorEl.classList.remove('is-hidden');\n                chipErrorEl.textContent = errorsPlural(counts.errorCount);\n            } else {\n                chipErrorEl.classList.add('is-hidden');\n            }\n\n            if (counts.warningCount > 0) {\n                chipWarningEl.classList.remove('is-hidden');\n                chipWarningEl.textContent = warningsPlural(counts.warningCount);\n            } else {\n                chipWarningEl.classList.add('is-hidden');\n            }\n\n            if (chipSuccessEl) {\n                if (counts.successCount > 0) {\n                    chipSuccessEl.classList.remove('is-hidden');\n                    chipSuccessEl.textContent = successesPlural(counts.successCount);\n                } else {\n                    chipSuccessEl.classList.add('is-hidden');\n                }\n            }\n\n            if (chipInfoEl) {\n                if (counts.infoCount > 0) {\n                    chipInfoEl.classList.remove('is-hidden');\n                    chipInfoEl.textContent = infosPlural(counts.infoCount);\n                } else {\n                    chipInfoEl.classList.add('is-hidden');\n                }\n            }\n\n            const hasAny = entries.size > 0;\n\n            if (!hasAny) {\n                panelEl.classList.remove('is-visible');\n                badgeEl.classList.remove('is-visible');\n                \/\/ Show the green \"Wniosek wygl\u0105da dobrze\" pill only when nothing is queued AND the\n                \/\/ user has actually started filling the form (otherwise a fresh, empty form would\n                \/\/ proudly announce it \"looks good\").\n                if (pendingSuppressed.size === 0 && hasInteracted) {\n                    successPillEl.classList.add('is-visible');\n                } else {\n                    successPillEl.classList.remove('is-visible');\n                }\n                return;\n            }\n\n            successPillEl.classList.remove('is-visible');\n\n            if (collapsed) {\n                panelEl.classList.remove('is-visible');\n                badgeEl.classList.add('is-visible');\n                badgeDotEl.classList.remove('issues-badge-dot--warning', 'issues-badge-dot--info', 'issues-badge-dot--success');\n                if (counts.errorCount > 0) {\n                    badgeTextEl.textContent = errorsPlural(counts.errorCount);\n                } else if (counts.warningCount > 0) {\n                    badgeDotEl.classList.add('issues-badge-dot--warning');\n                    badgeTextEl.textContent = warningsPlural(counts.warningCount);\n                } else if (counts.infoCount > 0) {\n                    badgeDotEl.classList.add('issues-badge-dot--info');\n                    badgeTextEl.textContent = infosPlural(counts.infoCount);\n                } else {\n                    badgeDotEl.classList.add('issues-badge-dot--success');\n                    badgeTextEl.textContent = successesPlural(counts.successCount);\n                }\n            } else {\n                panelEl.classList.add('is-visible');\n                badgeEl.classList.remove('is-visible');\n            }\n\n            \/\/ Mobile: show \"Poka\u017c wszystkie (N)\" when there are 2+ entries.\n            if (entries.size > 1) {\n                panelEl.classList.add('has-multiple');\n                if (mobileExpanded) {\n                    panelEl.classList.remove('mobile-collapsed');\n                    toggleAllText.textContent = 'Poka\u017c mniej';\n                    toggleAllBtn.setAttribute('aria-expanded', 'true');\n                } else {\n                    panelEl.classList.add('mobile-collapsed');\n                    toggleAllText.textContent = `Poka\u017c wszystkie (${entries.size})`;\n                    toggleAllBtn.setAttribute('aria-expanded', 'false');\n                }\n            } else {\n                panelEl.classList.remove('has-multiple', 'mobile-collapsed');\n                mobileExpanded = false;\n            }\n        }\n\n        \/\/ Rules whose section has not yet been \"opened\" by the user wait here instead of appearing in the panel.\n        const pendingSuppressed = new Map();\n\n        function isPayloadVisible(payload) {\n            if (payload && payload.bypassGate) return true;\n            if (!payload || typeof payload.sectionIndex !== 'number') return true;\n            return payload.sectionIndex < highestReachedSection;\n\t\t\t\/\/> this comment is used to circumvent the https:\/\/core.trac.wordpress.org\/ticket\/43785 bug\n        }\n\n        \/\/ Map<id, { timeoutId, el, payload }> for entries that are mid-fade-out. We track them so a\n        \/\/ follow-up upsert with the same id can cancel the pending DOM removal and re-attach the\n        \/\/ existing node to entries, instead of leaving an orphan and creating a duplicate.\n        const pendingRemovals = new Map();\n\n        function cancelPendingRemoval(id) {\n            const pending = pendingRemovals.get(id);\n            if (!pending) return;\n            clearTimeout(pending.timeoutId);\n            pendingRemovals.delete(id);\n            pending.el.classList.remove('is-entering');\n            if (!entries.has(id) && pending.el.parentNode) {\n                entries.set(id, { el: pending.el, payload: pending.payload });\n            }\n        }\n\n        function renderEntry(id, payload) {\n            cancelPendingRemoval(id);\n            if (entries.has(id)) {\n                const record = entries.get(id);\n                if (record.payload.severity !== payload.severity) {\n                    record.el.className = `issues-entry issues-entry--${payload.severity}`;\n                    record.el.querySelector('.issues-entry-icon').innerHTML = severityIconSvg(payload.severity);\n                }\n                applyPayload(record.el, payload);\n                record.payload = payload;\n            } else {\n                const el = buildEntryEl(id, payload);\n                el.classList.add('is-entering');\n                bodyEl.appendChild(el);\n                requestAnimationFrame(function () {\n                    el.classList.remove('is-entering');\n                });\n                entries.set(id, { el: el, payload: payload });\n            }\n        }\n\n        function upsert(id, payload) {\n            if (isPayloadVisible(payload)) {\n                pendingSuppressed.delete(id);\n                renderEntry(id, payload);\n            } else {\n                \/\/ Section not opened yet - park the rule, do not render it.\n                pendingSuppressed.set(id, payload);\n                if (entries.has(id)) {\n                    \/\/ A previously visible rule became gated again (rare); remove it.\n                    removeFromVisible(id);\n                }\n            }\n            render();\n        }\n\n        function removeFromVisible(id) {\n            const record = entries.get(id);\n            if (!record) return;\n            \/\/ If a previous removal for this id is already in flight, cancel it so we don't end up\n            \/\/ with two timers racing to detach the same node.\n            const existing = pendingRemovals.get(id);\n            if (existing) clearTimeout(existing.timeoutId);\n            entries.delete(id);\n            const el = record.el;\n            const payload = record.payload;\n            el.classList.add('is-entering');\n            const timeoutId = setTimeout(function () {\n                pendingRemovals.delete(id);\n                if (el.parentNode) el.parentNode.removeChild(el);\n            }, 150);\n            pendingRemovals.set(id, { timeoutId: timeoutId, el: el, payload: payload });\n        }\n\n        function remove(id) {\n            pendingSuppressed.delete(id);\n            if (entries.has(id)) {\n                removeFromVisible(id);\n                render();\n            }\n        }\n\n        function removeMatching(prefix) {\n            const toRemove = [];\n            entries.forEach(function (_, id) {\n                if (id.indexOf(prefix) === 0) toRemove.push(id);\n            });\n            pendingSuppressed.forEach(function (_, id) {\n                if (id.indexOf(prefix) === 0 && toRemove.indexOf(id) === -1) toRemove.push(id);\n            });\n            toRemove.forEach(remove);\n        }\n\n        function has(id) {\n            return entries.has(id);\n        }\n\n        function flushPending() {\n            const toFlush = [];\n            pendingSuppressed.forEach(function (payload, id) {\n                if (isPayloadVisible(payload)) toFlush.push(id);\n            });\n            toFlush.forEach(function (id) {\n                const payload = pendingSuppressed.get(id);\n                pendingSuppressed.delete(id);\n                renderEntry(id, payload);\n            });\n            if (toFlush.length > 0) render();\n        }\n\n        function notifyFocusedSection(sectionIndex) {\n            if (typeof sectionIndex !== 'number' || !(sectionIndex > 0)) return;\n            hasInteracted = true;\n            if (sectionIndex > highestReachedSection) {\n                highestReachedSection = sectionIndex;\n                flushPending();\n            }\n        }\n\n        function markInteracted() {\n            if (hasInteracted) return;\n            hasInteracted = true;\n            render();\n        }\n\n        function getHighestReachedSection() {\n            return highestReachedSection;\n        }\n\n        function snapshot() {\n            return recomputeCounts();\n        }\n\n        function markSubmitAttempted() {\n            submitAttempted = true;\n            \/\/ Submit attempt = user reached the end of the form; flush everything queued in earlier sections.\n            notifyFocusedSection(6);\n        }\n\n        function isSubmitAttempted() {\n            return submitAttempted;\n        }\n\n        function setCollapsed(value) {\n            collapsed = !!value;\n            render();\n        }\n\n        function pulsePanel() {\n            const target = panelEl.classList.contains('is-visible') ? panelEl : badgeEl;\n            if (!target.classList.contains('is-visible')) return;\n            target.style.transition = 'transform 0.2s ease-out';\n            target.style.transform = 'scale(1.04)';\n            setTimeout(function () {\n                target.style.transform = 'scale(1)';\n                setTimeout(function () { target.style.transition = ''; target.style.transform = ''; }, 220);\n            }, 200);\n        }\n\n        closeBtn.addEventListener('click', function () { setCollapsed(true); });\n        badgeEl.addEventListener('click', function () { setCollapsed(false); });\n        toggleAllBtn.addEventListener('click', function () {\n            mobileExpanded = !mobileExpanded;\n            render();\n        });\n\n        return {\n            upsert: upsert,\n            remove: remove,\n            removeMatching: removeMatching,\n            has: has,\n            snapshot: snapshot,\n            markSubmitAttempted: markSubmitAttempted,\n            isSubmitAttempted: isSubmitAttempted,\n            setCollapsed: setCollapsed,\n            goToField: goToField,\n            pulsePanel: pulsePanel,\n            render: render,\n            notifyFocusedSection: notifyFocusedSection,\n            getHighestReachedSection: getHighestReachedSection,\n            markInteracted: markInteracted\n        };\n    })();\n\n\t\/* \u2500\u2500 Modal komunikat\u00f3w \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n\n    let modalOnClose = null;\n\n    function showModal(type, title, message, onClose) {\n        \/\/ Sprawd\u017a czy parametry nie s\u0105 puste\n        if (!title && !message) {\n            console.error('showModal: brak tytu\u0142u i wiadomo\u015bci');\n            return;\n        }\n\n        \/\/ Jednorazowy callback wywo\u0142ywany przy zamkni\u0119ciu (np. redirect po sukcesie)\n        modalOnClose = (typeof onClose === 'function') ? onClose : null;\n\n        const modal = document.getElementById('customModal');\n        const modalIcon = document.getElementById('modalIcon');\n        const modalTitle = document.getElementById('modalTitle');\n        const modalMessage = document.getElementById('modalMessage');\n        \n        \/\/ Ustawienie ikony i klasy w zale\u017cno\u015bci od typu\n        if (type === 'error') {\n            modalIcon.innerHTML = '\u274c';\n            modalIcon.className = 'modal-icon error';\n        } else if (type === 'success') {\n            modalIcon.innerHTML = '\u2705';\n            modalIcon.className = 'modal-icon success';\n        } else if (type === 'warning') {\n            modalIcon.innerHTML = '\u26a0\ufe0f';\n            modalIcon.className = 'modal-icon error';\n        } else {\n            modalIcon.innerHTML = '\u2139\ufe0f';\n            modalIcon.className = 'modal-icon';\n        }\n        \n        modalTitle.textContent = title || 'Powiadomienie';\n        modalMessage.textContent = message || '';\n        \n        \/\/ Pokazanie modala\n        modal.classList.add('show');\n        \n        \/\/ Zapobieganie przewijaniu strony w tle\n        document.body.style.overflow = 'hidden';\n        \n        \/\/ Fokus na przycisku zamkni\u0119cia dla dost\u0119pno\u015bci\n        setTimeout(() => {\n            document.getElementById('modalCloseBtn').focus();\n        }, 100);\n    }\n    \n    function hideModal() {\n        const modal = document.getElementById('customModal');\n        modal.classList.remove('show');\n\n        \/\/ Przywr\u00f3\u0107 przewijanie strony\n        document.body.style.overflow = '';\n\n        \/\/ Uruchom jednorazowy callback zamkni\u0119cia (i wyzeruj go najpierw,\n        \/\/ \u017ceby ewentualny redirect nie wykona\u0142 si\u0119 dwa razy)\n        const cb = modalOnClose;\n        modalOnClose = null;\n        if (cb) cb();\n    }\n    \n    \/\/ Event listeners dla zamykania modala\n    document.getElementById('modalCloseBtn').addEventListener('click', hideModal);\n    \n    \/\/ Zamkni\u0119cie modala klawiszem Enter na przycisku\n    document.getElementById('modalCloseBtn').addEventListener('keydown', function(e) {\n        if (e.key === 'Enter') {\n            hideModal();\n        }\n    });\n    \n    \/\/ Zamkni\u0119cie modala przy klikni\u0119ciu w t\u0142o\n    document.getElementById('customModal').addEventListener('click', function(e) {\n        if (e.target === this) {\n            hideModal();\n        }\n    });\n    \n    \/\/ Zamkni\u0119cie modala klawiszem Escape\n    document.addEventListener('keydown', function(e) {\n        if (e.key === 'Escape') {\n            const modal = document.getElementById('customModal');\n            if (modal.classList.contains('show')) {\n                hideModal();\n            }\n        }\n    });\n\n\t\/* \u2500\u2500 Dodawanie \u015bwiadczenia (builder) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n\n    document.getElementById('addService').addEventListener('click', function() {\n        const servicesContainer = document.getElementById('servicesContainer');\n        const serviceCount = document.querySelectorAll('.service-group').length;\n        const newService = document.createElement('div');\n        newService.classList.add('service-group', 'service-subsection');\n        newService.setAttribute('data-service-index', serviceCount);\n        newService.innerHTML = `\n            <div class=\"service-subsection-header\">\n                <h3 class=\"service-subsection-title\">\u015awiadczenie ${serviceCount + 1}<\/h3>\n                <button type=\"button\" class=\"remove-service confirm-btn confirm-btn-back remove-service-btn\">\n                    Usu\u0144 to \u015bwiadczenie\n                <\/button>\n            <\/div>\n            <div class=\"mb-4 service\">\n                <label class=\"block text-gray-700\">Nazwa \u015awiadczenia *<\/label>\n                <select name=\"serviceName[]\" class=\"block w-full border border-gray-300 rounded-md p-2\" required>\n                    <option value=\"\">Wybierz kategori\u0119<\/option>\n                    <option value=\"Badania obrazowe\">Badania obrazowe<\/option>\n                    <option value=\"Us\u0142uga stacjonarna\">Us\u0142uga stacjonarna<\/option>\n                    <option value=\"Wizyta domowa\">Wizyta domowa<\/option>\n                    <option value=\"Rehabilitacje\">Rehabilitacje<\/option>\n                    <option value=\"Sprz\u0119t rehabilitacyjny\">Sprz\u0119t rehabilitacyjny<\/option>\n                    <option value=\"Transport\">Transport<\/option>\n                    <option value=\"Badania laboratoryjne\">Badania laboratoryjne<\/option>\n                    <option value=\"Us\u0142uga Assistance (np. korepetycje)\">Us\u0142uga Assistance (np. korepetycje)<\/option>\n                    <option value=\"Us\u0142uga stomatologiczna\">Us\u0142uga stomatologiczna<\/option>\n                    <option value=\"Badania medycyny pracy\">Badania medycyny pracy<\/option>\n                <\/select>\n                <div class=\"mt-3 px-4 py-3 rounded-lg warning-box\">\n                    <p class=\"text-sm warning-box-text\"><span class=\"font-bold\">Uwaga!<\/span> Wybranie z\u0142ego \u015bwiadczenia spowoduje odrzucenie wniosku refundacyjnego.<\/p>\n                <\/div>\n            <\/div>\n            <div class=\"mb-4 service hidden\">\n                <label class=\"block text-gray-700\">Czy w ramach wizyty lekarskiej by\u0142y realizowane dodatkowe badania? *<\/label>\n                <div class=\"flex gap-4\">\n                    <label class=\"flex items-center\">\n                        <input type=\"radio\" name=\"additionalTests_${serviceCount}\" value=\"tak\" class=\"mr-2 additional-tests-radio\">\n                        <span>Tak<\/span>\n                    <\/label>\n                    <label class=\"flex items-center\">\n                        <input type=\"radio\" name=\"additionalTests_${serviceCount}\" value=\"nie\" class=\"mr-2 additional-tests-radio\">\n                        <span>Nie<\/span>\n                    <\/label>\n                <\/div>\n            <\/div>\n            <div class=\"mb-4 service additional-tests-details hidden\">\n                <label class=\"block text-gray-700\">Jakie badania by\u0142y realizowane? *<\/label>\n                <input type=\"text\" name=\"examName[]\" class=\"block w-full border border-gray-300 rounded-md p-2\">\n            <\/div>\n            <div class=\"form-grid-2\">\n                <div class=\"service\">\n                    <label class=\"block text-gray-700\">Data wykonania *<\/label>\n                    <input type=\"date\" name=\"serviceDate[]\" class=\"block w-full border border-gray-300 rounded-md p-2 service-date\" required>\n                    <p class=\"service-date-error text-red-500 text-sm mt-1 hidden\">Data wykonania \u015bwiadczenia musi mie\u015bci\u0107 si\u0119 w ostatnich 3 latach.<\/p>\n                <\/div>\n                <div class=\"service\">\n                    <label class=\"block text-gray-700\">Nazwa plac\u00f3wki *<\/label>\n                    <input type=\"text\" name=\"servicePlace[]\" maxlength=\"200\" class=\"block w-full border border-gray-300 rounded-md p-2\" required>\n                <\/div>\n                <div class=\"service form-grid-2-full\">\n                    <label class=\"block text-gray-700\">Adres plac\u00f3wki *<\/label>\n                    <input type=\"text\" name=\"serviceAddress[]\" maxlength=\"100\" class=\"block w-full border border-gray-300 rounded-md p-2\" required>\n                <\/div>\n                <div class=\"service\">\n                    <label class=\"block text-gray-700\">Kod pocztowy plac\u00f3wki *<\/label>\n                    <input type=\"text\" name=\"servicePostalCode[]\" class=\"block w-full border border-gray-300 rounded-md p-2 servicePostalCode\" required>\n                    <p class=\"servicePostalCodeError text-red-500 text-sm mt-1 hidden\">Wprowad\u017a poprawny kod pocztowy w formacie 00-000.<\/p>\n                <\/div>\n                <div class=\"service\">\n                    <label class=\"block text-gray-700\">Miejscowo\u015b\u0107 plac\u00f3wki *<\/label>\n                    <input type=\"text\" name=\"serviceCity[]\" maxlength=\"100\" class=\"block w-full border border-gray-300 rounded-md p-2\" required>\n                <\/div>\n                <div class=\"service form-grid-2-full\">\n                    <label class=\"block text-gray-700\">NIP plac\u00f3wki *<\/label>\n                    <input type=\"text\" name=\"serviceNIP[]\" class=\"block w-full border border-gray-300 rounded-md p-2 service-nip\" inputmode=\"numeric\" placeholder=\"np. 1234567890\" required>\n                    <p class=\"service-nip-error text-red-500 text-sm mt-1 hidden\">Wprowad\u017a poprawny numer NIP (10 cyfr).<\/p>\n                    <p class=\"service-nip-hint field-info-hint hidden\"><\/p>\n                <\/div>\n                <div class=\"service\">\n                    <label class=\"block text-gray-700\">Kwota (PLN) *<\/label>\n                    <input type=\"text\" name=\"amount[]\" maxlength=\"12\" class=\"block w-full border border-gray-300 rounded-md p-2 amount-input\" required>\n                    <p class=\"amount-error text-red-500 text-sm mt-1 hidden\">Wprowad\u017a poprawn\u0105 kwot\u0119 (np. 123,45 lub 123.45).<\/p>\n                <\/div>\n                <div class=\"service\">\n                    <label class=\"block text-gray-700\">Nr faktury\/rachunku *<\/label>\n                    <input type=\"text\" name=\"invoiceNumber[]\" class=\"block w-full border border-gray-300 rounded-md p-2 invoice-number\" maxlength=\"50\" required>\n                    <p class=\"invoice-number-error text-red-500 text-sm mt-1 hidden\">Numer faktury\/rachunku nie mo\u017ce przekracza\u0107 50 znak\u00f3w.<\/p>\n                <\/div>\n            <\/div>\n            <div class=\"service\">\n                <label class=\"block text-gray-700 font-bold mb-1\">Za\u0142\u0105cz faktur\u0119\/rachunek *<\/label>\n                <div class=\"file-upload-zone\" data-upload-for=\"invoiceFile${serviceCount}\" data-zone-role=\"invoice\">\n                    <input type=\"file\" name=\"invoiceFile${serviceCount}\" accept=\"image\/*,.pdf,.heic,.heif\" data-was-required=\"true\">\n                    <p class=\"text-sm text-gray-600\"><span class=\"file-upload-browse\">Wybierz plik<\/span> lub przeci\u0105gnij tutaj<\/p>\n                    <div class=\"file-upload-meta\">Zdj\u0119cie lub PDF &middot; maks. 10 MB<\/div>\n                <\/div>\n                <div class=\"file-list\" data-list-for=\"invoiceFile${serviceCount}\" data-list-role=\"invoice\"><\/div>\n            <\/div>\n            <div class=\"service mt-5\">\n                <label class=\"block text-gray-700 mb-1\">Za\u0142\u0105cz dokumentacj\u0119 medyczn\u0105 dotycz\u0105c\u0105 poniesionego kosztu<\/label>\n                <div class=\"file-upload-zone\" data-upload-for=\"medicalDocs${serviceCount}\" data-zone-role=\"medical\" data-multiple=\"true\">\n                    <input type=\"file\" name=\"medicalDocs${serviceCount}\" multiple accept=\"image\/*,.pdf,.heic,.heif\">\n                    <p class=\"text-sm text-gray-600\"><span class=\"file-upload-browse\">Wybierz dodatkowe pliki<\/span> lub przeci\u0105gnij je tutaj<\/p>\n                    <div class=\"file-upload-meta\">Zdj\u0119cia i PDF &middot; maks. 10 MB na plik &middot; mo\u017cna dodawa\u0107 wielokrotnie<\/div>\n                <\/div>\n                <div class=\"file-list\" data-list-for=\"medicalDocs${serviceCount}\" data-list-role=\"medical\"><\/div>\n            <\/div>\n        `;\n        servicesContainer.appendChild(newService);\n\n        \/\/ Aktualizuj numeracj\u0119 po dodaniu\n        updateServiceNumbers();\n        \/\/ Aktualizuj widoczno\u015b\u0107 przycisk\u00f3w usuwania\n        updateRemoveButtonsVisibility();\n        \/\/ Rewaliduj panel weryfikacji - mo\u017ce pojawi\u0107 si\u0119 nowe ostrze\u017cenie dla nowego \u015bwiadczenia\n        if (window.revalidateFormIssues) window.revalidateFormIssues(true);\n        if (window.refundVerify) window.refundVerify.notifyServiceAdded();\n    });\n\n\t\/* \u2500\u2500 Usuwanie \u015bwiadczenia (modal + przeindeksowanie) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n\n    let pendingDeleteServiceGroup = null;\n\n    document.addEventListener('click', function(e) {\n        if (e.target.classList.contains('remove-service')) {\n            pendingDeleteServiceGroup = e.target.closest('.service-group');\n            const modal = document.getElementById('deleteServiceModal');\n            modal.classList.add('show');\n            document.body.style.overflow = 'hidden';\n        }\n    });\n\n    document.getElementById('deleteServiceCancelBtn').addEventListener('click', function() {\n        pendingDeleteServiceGroup = null;\n        const modal = document.getElementById('deleteServiceModal');\n        modal.classList.remove('show');\n        document.body.style.overflow = '';\n    });\n\n    document.getElementById('deleteServiceModal').addEventListener('click', function(e) {\n        if (e.target === this) {\n            pendingDeleteServiceGroup = null;\n            this.classList.remove('show');\n            document.body.style.overflow = '';\n        }\n    });\n\n    document.getElementById('deleteServiceConfirmBtn').addEventListener('click', function() {\n        const modal = document.getElementById('deleteServiceModal');\n        modal.classList.remove('show');\n        document.body.style.overflow = '';\n\n        if (pendingDeleteServiceGroup) {\n            \/\/ Capture the removed origIdx BEFORE the DOM node is detached - refundVerify\n            \/\/ needs it to shift its per-service verdict cache and dirty set.\n            const removedIdxRaw = pendingDeleteServiceGroup.getAttribute('data-service-index');\n            const removedIdx = parseInt(removedIdxRaw, 10);\n\n            \/\/ Drop file store entries before the DOM node goes away - both the invoice and\n            \/\/ the medical-documentation zone, otherwise the removed service's documentation\n            \/\/ would still be posted in attachments[].\n            pendingDeleteServiceGroup.querySelectorAll('.file-upload-zone').forEach(zone => {\n                delete fileStores[zone.dataset.uploadFor];\n            });\n\n            \/\/ Abort any in-flight RPWDL lookup on the group being removed\n            if (pendingDeleteServiceGroup._rpwdlAbort) {\n                try { pendingDeleteServiceGroup._rpwdlAbort.abort(); } catch (e) { \/* ignored *\/ }\n            }\n            if (pendingDeleteServiceGroup._rpwdlDebounceTimer) {\n                clearTimeout(pendingDeleteServiceGroup._rpwdlDebounceTimer);\n            }\n\n            pendingDeleteServiceGroup.remove();\n            pendingDeleteServiceGroup = null;\n            updateServiceNumbers();\n            updateRemoveButtonsVisibility();\n\n            \/\/ Per-field validators rebind after a service is removed\n            setTimeout(function() {\n                setupServicePostalCodeValidation();\n                setupAmountValidation();\n                setupInvoiceNumberValidation();\n                setupServiceDateValidation();\n            }, 100);\n\n            \/\/ Indices shifted: rekey each surviving group's RPWDL entries to its new idx\n            \/\/ without re-fetching. If the group already has a cached verdict from a prior\n            \/\/ lookup we just replay it under the new idx (zero network); otherwise we ask\n            \/\/ handleNipChange to start one only if the NIP+date are both valid.\n            document.querySelectorAll('.service-group').forEach(function (group) {\n                const gIdx = getServiceIndex(group);\n                formIssues.remove(`warn.service.${gIdx}.rpwdl.notFound`);\n                formIssues.remove(`warn.service.${gIdx}.rpwdl.inactive`);\n                formIssues.remove(`success.service.${gIdx}.rpwdl.ok`);\n                if (group._rpwdlLastVerdict) {\n                    applyRpwdlVerdict(group);\n                } else {\n                    \/\/ No cached verdict (lookup never completed for this group, or was\n                    \/\/ cleared by an invalid edit). Fall through to handleNipChange so a\n                    \/\/ fresh lookup can fire IF the inputs are currently valid; otherwise\n                    \/\/ the gate inside handleNipChange short-circuits with no network.\n                    group.dataset.rpwdlLookupKey = '';\n                    group.dataset.rpwdlLookupStatus = '';\n                    handleNipChange(group, true);\n                }\n            });\n\n            \/\/ Revalidate the issues panel since indices shifted\n            if (window.revalidateFormIssues) window.revalidateFormIssues(true);\n            if (window.refundVerify && !isNaN(removedIdx)) {\n                window.refundVerify.notifyServiceRemoved(removedIdx);\n            }\n        }\n    });\n\n\t\/* \u2500\u2500 Przeindeksowanie \u015bwiadcze\u0144 i plik\u00f3w \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n\n    function updateServiceNumbers() {\n        const serviceGroups = document.querySelectorAll('.service-group');\n        serviceGroups.forEach((group, index) => {\n            \/\/ Aktualizuj data-service-index\n            group.setAttribute('data-service-index', index);\n\n            \/\/ Aktualizuj nazwy radio button\u00f3w dla dodatkowych bada\u0144\n            const radioButtons = group.querySelectorAll('.additional-tests-radio');\n            radioButtons.forEach(radio => {\n                radio.name = `additionalTests_${index}`;\n            });\n\n            \/\/ Aktualizuj widoczny tytu\u0142 podsekcji \u015bwiadczenia\n            const titleEl = group.querySelector('.service-subsection-title');\n            if (titleEl) {\n                titleEl.textContent = `\u015awiadczenie ${index + 1}`;\n            }\n        });\n        \/\/ Renumbering services also has to reattach files\/dropzones so the fileStores key and the\n        \/\/ file input name stay in sync with the current group index.\n        updateFileInputNames();\n    }\n\n    \/\/ Funkcja do aktualizacji nazw plik\u00f3w po usuni\u0119ciu \u015bwiadczenia.\n    \/\/ Both zones of a group have to be rekeyed - missing one would leave its files under a\n    \/\/ stale key that no longer belongs to any visible service, so they would silently ride\n    \/\/ along into the payload.\n    function updateFileInputNames() {\n        \/\/ Zbierz stare store'y i przeindeksuj\n        const newStores = {};\n        const serviceGroups = document.querySelectorAll('.service-group');\n        serviceGroups.forEach((group, index) => {\n            group.querySelectorAll('.file-upload-zone').forEach(zone => {\n                const prefix = ZONE_KEY_PREFIX[zone.dataset.zoneRole];\n                if (!prefix) return;\n\n                const oldKey = zone.dataset.uploadFor;\n                const fileInput = zone.querySelector('input[type=\"file\"]');\n                const fileList = group.querySelector(`.file-list[data-list-for=\"${oldKey}\"]`);\n                if (!fileInput) return;\n\n                const newKey = `${prefix}${index}`;\n\n                \/\/ Przenie\u015b pliki ze starego klucza do nowego\n                if (fileStores[oldKey] && oldKey !== newKey) {\n                    newStores[newKey] = fileStores[oldKey];\n                    delete fileStores[oldKey];\n                } else if (fileStores[newKey]) {\n                    newStores[newKey] = fileStores[newKey];\n                } else if (fileStores[oldKey]) {\n                    newStores[newKey] = fileStores[oldKey];\n                }\n\n                zone.dataset.uploadFor = newKey;\n                fileInput.name = newKey;\n                if (fileList) {\n                    fileList.dataset.listFor = newKey;\n                }\n            });\n        });\n\n        \/\/ Zastosuj przeindeksowane store'y\n        Object.keys(newStores).forEach(key => {\n            fileStores[key] = newStores[key];\n        });\n\n        \/\/ Rerenderuj listy plik\u00f3w\n        serviceGroups.forEach((group, index) => {\n            Object.keys(ZONE_KEY_PREFIX).forEach(role => {\n                renderFileList(`${ZONE_KEY_PREFIX[role]}${index}`);\n            });\n        });\n    }\n\n    \/\/ Funkcja do kontrolowania widoczno\u015bci przycisk\u00f3w usuwania\n    function updateRemoveButtonsVisibility() {\n        const serviceGroups = document.querySelectorAll('.service-group');\n        const removeButtons = document.querySelectorAll('.remove-service');\n        \n        \/\/ Poka\u017c przyciski usuwania tylko gdy jest wi\u0119cej ni\u017c jedno \u015bwiadczenie\n        removeButtons.forEach(button => {\n            if (serviceGroups.length > 1) {\n                button.classList.remove('remove-service-btn--hidden');\n            } else {\n                button.classList.add('remove-service-btn--hidden');\n            }\n        });\n    }\n\n\t\/* \u2500\u2500 NIP \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n\n    function normalizeNIP(nip) {\n        if (typeof nip !== 'string') return '';\n        \/\/ Strip every non-digit so any separator (space, hyphen, dot, slash, stray letter)\n        \/\/ is removed before length\/checksum checks. The input handler in wireRpwdlLookup\n        \/\/ relies on this returning digits only, then slices to 10.\n        return nip.replace(\/\\D\/g, '');\n    }\n\n    function validateNIP(nip) {\n        const clean = normalizeNIP(nip);\n        if (!\/^\\d{10}$\/.test(clean)) return false;\n        const weights = [6, 5, 7, 2, 3, 4, 5, 6, 7];\n        let sum = 0;\n        for (let i = 0; i < 9; i++) {\n\t\t\t\/\/> this comment is used to circumvent the https:\/\/core.trac.wordpress.org\/ticket\/43785 bug\n            sum += parseInt(clean.charAt(i), 10) * weights[i];\n        }\n        const check = sum % 11;\n        if (check === 10) return false;\n        return check === parseInt(clean.charAt(9), 10);\n    }\n\n\t\/* \u2500\u2500 Daty \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n\n    function isValidIsoDate(s) {\n        \/\/ Parse YYYY-MM-DD strictly via the regex captures and Date.UTC, mirroring the\n        \/\/ existing parseIsoDate helper used elsewhere. Avoids Date.parse, which is\n        \/\/ engine- and timezone-dependent for date-only strings.\n        if (typeof s !== 'string') return false;\n        const m = \/^(\\d{4})-(\\d{2})-(\\d{2})$\/.exec(s);\n        if (!m) return false;\n        const year = parseInt(m[1], 10);\n        const month = parseInt(m[2], 10);\n        const day = parseInt(m[3], 10);\n        const d = new Date(Date.UTC(year, month - 1, day));\n        if (isNaN(d.getTime())) return false;\n        \/\/ Round-trip the UTC components back to the original string. Catches roll-over\n        \/\/ cases like \"2026-02-31\" (silently becomes 2026-03-03) and \"2026-13-01\".\n        return d.getUTCFullYear() === year\n            && d.getUTCMonth() === month - 1\n            && d.getUTCDate() === day;\n    }\n\n    function validateDateNotFromFuture(dateString) {\n        if (!dateString) return true; \/\/ Puste pole mo\u017ce by\u0107, wymagane sprawdza HTML\n\n        const inputDate = new Date(dateString);\n        const today = new Date();\n        today.setHours(23, 59, 59, 999); \/\/ Ustaw na koniec dnia, \u017ceby dzisiejsza data by\u0142a OK\n\n        return inputDate <= today;\n\t\t\/\/> this comment is used to circumvent the https:\/\/core.trac.wordpress.org\/ticket\/43785 bug\n    }\n\n    function validateDateWithin3Years(dateString) {\n        if (!dateString) return true;\n        if (!isValidIsoDate(dateString)) return false;\n        const [year, month, day] = dateString.split('-').map(Number);\n        const inputDate = new Date(year, month - 1, day);\n        const threshold = new Date();\n        threshold.setHours(0, 0, 0, 0);\n        threshold.setFullYear(threshold.getFullYear() - 3);\n        return inputDate >= threshold;\n    }\n\n    function toLocalIsoDate(d) {\n        const yyyy = d.getFullYear();\n        const mm = String(d.getMonth() + 1).padStart(2, '0');\n        const dd = String(d.getDate()).padStart(2, '0');\n        return `${yyyy}-${mm}-${dd}`;\n    }\n\n    function get3YearsAgoIso() {\n        const d = new Date();\n        d.setHours(0, 0, 0, 0);\n        d.setFullYear(d.getFullYear() - 3);\n        return toLocalIsoDate(d);\n    }\n\n    function getTodayIso() {\n        return toLocalIsoDate(new Date());\n    }\n\n    function applyDateBoundsToServiceDate(input) {\n        if (!input) return;\n        input.setAttribute('min', get3YearsAgoIso());\n        input.setAttribute('max', getTodayIso());\n    }\n\n\t\/* \u2500\u2500 Zgody \u2014 czyszczenie b\u0142\u0119du \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n\n    \/\/ Usuwanie b\u0142\u0119du z checkbox\u00f3w zg\u00f3d po zaznaczeniu\n    document.querySelectorAll('.consent-checkbox input[type=\"checkbox\"]').forEach(checkbox => {\n        checkbox.addEventListener('change', function() {\n            const label = this.closest('.consent-checkbox');\n            if (this.checked) {\n                label.classList.remove('consent-error');\n            }\n        });\n    });\n\n\t\/* \u2500\u2500 Dodatkowe badania + init uploadu \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n\n    afterSetup(function() {\n        document.body.addEventListener('change', function(e) {\n            if (e.target.classList.contains('additional-tests-radio')) {\n                const serviceGroup = e.target.closest('.service-group');\n                const detailsDiv = serviceGroup.querySelector('.additional-tests-details');\n                const detailsInput = detailsDiv.querySelector('input');\n                \n                if (e.target.value === 'tak') {\n                    detailsDiv.classList.remove('hidden');\n                    detailsInput.required = true;\n                } else {\n                    detailsDiv.classList.add('hidden');\n                    detailsInput.required = false;\n                    detailsInput.value = '';\n                }\n            }\n        });\n        \n        \/\/ Inicjalizacja uploadu plik\u00f3w\n        initFileUploads();\n    });\n\n\t\/* \u2500\u2500 Upload plik\u00f3w \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n\n    const fileStores = {};\n\n    \/\/ Every service group owns two upload zones, told apart by data-zone-role. The store key\n    \/\/ stays index-suffixed per role so the tiles render under the right service, but at submit\n    \/\/ time all `medicalDocs*` stores are poured into one attachments[] array (LESS-14852).\n    const ZONE_KEY_PREFIX = { invoice: 'invoiceFile', medical: 'medicalDocs' };\n    const MEDICAL_DOCS_KEY = \/^medicalDocs\\d+$\/;\n\n    function isMedicalDocsKey(storeKey) {\n        return MEDICAL_DOCS_KEY.test(storeKey);\n    }\n\n    function validateFileType(file) {\n        const acceptedTypes = ['image\/jpeg', 'image\/png', 'image\/gif', 'image\/jpg', 'image\/webp', 'image\/heic', 'image\/heif', 'application\/pdf'];\n        const acceptedExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.heic', '.heif', '.pdf'];\n        \/\/ Cz\u0119\u015b\u0107 przegl\u0105darek nie ustawia file.type dla .heic\/.heif (pusty MIME na Windows) \u2014 fallback po rozszerzeniu.\n        \/\/ Bezpieczne: autorytatywny check robi backend (IMS, magic-bytes) \u2014 podmienione pliki i tak odpadaj\u0105.\n        const fileName = file.name.toLowerCase();\n        return acceptedTypes.includes(file.type) || acceptedExtensions.some(ext => fileName.endsWith(ext));\n    }\n\n    function validateFileSize(file) {\n        const maxSize = 10 * 1024 * 1024;\n        return file.size <= maxSize;\n\t\t\/\/> this comment is used to circumvent the https:\/\/core.trac.wordpress.org\/ticket\/43785 bug\n    }\n\n    function formatFileSize(bytes) {\n        if (bytes === 0) return '0 B';\n        const k = 1024;\n        const sizes = ['B', 'KB', 'MB', 'GB'];\n        const i = Math.floor(Math.log(bytes) \/ Math.log(k));\n        return parseFloat((bytes \/ Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];\n    }\n\n    function getFileIcon(file) {\n        if (file.type === 'application\/pdf') {\n            return '<svg viewBox=\"0 0 14 14\" fill=\"none\"><path d=\"M3 1h5l4 4v8H3V1z\" stroke=\"currentColor\" stroke-width=\"1.2\"\/><path d=\"M8 1v4h4\" stroke=\"currentColor\" stroke-width=\"1.2\"\/><\/svg>';\n        }\n        return '<svg viewBox=\"0 0 14 14\" fill=\"none\"><rect x=\"1.5\" y=\"2\" width=\"11\" height=\"10\" rx=\"1.5\" stroke=\"currentColor\" stroke-width=\"1.2\"\/><circle cx=\"5\" cy=\"6\" r=\"1.2\" stroke=\"currentColor\" stroke-width=\"1\"\/><path d=\"M1.5 10l3-3 2 2 2.5-2.5L12.5 10\" stroke=\"currentColor\" stroke-width=\"1\"\/><\/svg>';\n    }\n\n    function renderFileList(storeKey) {\n        const listEl = document.querySelector(`.file-list[data-list-for=\"${storeKey}\"]`);\n        if (!listEl) return;\n\n        const files = fileStores[storeKey] || [];\n        listEl.innerHTML = '';\n\n        files.forEach((file, index) => {\n            const item = document.createElement('div');\n            item.className = 'file-list-item';\n            item.innerHTML = `\n                <div class=\"file-list-item-info\">\n                    <div class=\"file-list-item-icon\">${getFileIcon(file)}<\/div>\n                    <span class=\"file-list-item-name\">${file.name}<\/span>\n                    <span class=\"file-list-item-size\">${formatFileSize(file.size)}<\/span>\n                <\/div>\n                <button type=\"button\" class=\"file-list-item-remove\" data-store=\"${storeKey}\" data-index=\"${index}\">\n                    <svg viewBox=\"0 0 14 14\" fill=\"none\"><path d=\"M3 3l8 8M11 3l-8 8\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"\/><\/svg>\n                <\/button>\n            `;\n            listEl.appendChild(item);\n        });\n\n        const zone = document.querySelector(`.file-upload-zone[data-upload-for=\"${storeKey}\"]`);\n        if (zone) {\n            \/\/ Wyczy\u015b\u0107 czerwon\u0105 ramk\u0119 po dodaniu pliku\n            if (files.length > 0) {\n                zone.style.borderColor = '';\n            }\n            \/\/ A single-file zone hides itself once filled and comes back when the tile is\n            \/\/ removed - otherwise the live dropzone sitting next to the tile would silently\n            \/\/ overwrite the file just picked. Multi-file zones stay put by design.\n            const acceptsMany = zone.dataset.multiple === 'true';\n            zone.classList.toggle('file-upload-zone--filled', !acceptsMany && files.length > 0);\n        }\n    }\n\n    function addFilesToStore(storeKey, newFiles, isMultiple) {\n        if (!fileStores[storeKey]) {\n            fileStores[storeKey] = [];\n        }\n\n        let hasInvalidFile = false;\n        let hasOversizedFile = false;\n        const validFiles = [];\n\n        for (let i = 0; i < newFiles.length; i++) {\n\t\t\/\/> this comment is used to circumvent the https:\/\/core.trac.wordpress.org\/ticket\/43785 bug\n            const file = newFiles[i];\n            if (!validateFileType(file)) {\n                hasInvalidFile = true;\n                break;\n            }\n            if (!validateFileSize(file)) {\n                hasOversizedFile = true;\n                break;\n            }\n            \/\/ Sprawd\u017a duplikaty po nazwie i rozmiarze\n            const isDuplicate = fileStores[storeKey].some(\n                existing => existing.name === file.name && existing.size === file.size\n            );\n            if (!isDuplicate) {\n                validFiles.push(file);\n            }\n        }\n\n        if (hasInvalidFile) {\n            showModal('error', 'B\u0142\u0105d formatu pliku', 'Wykryto niedozwolony format pliku. Dozwolone s\u0105 tylko zdj\u0119cia i pliki PDF.');\n            return false;\n        }\n\n        if (hasOversizedFile) {\n            showModal('error', 'B\u0142\u0105d rozmiaru pliku', 'Wykryto plik przekraczaj\u0105cy maksymalny rozmiar 10MB. Ka\u017cdy plik nie mo\u017ce by\u0107 wi\u0119kszy ni\u017c 10MB.');\n            return false;\n        }\n\n        if (isMultiple) {\n            fileStores[storeKey] = fileStores[storeKey].concat(validFiles);\n        } else {\n            fileStores[storeKey] = validFiles.length > 0 ? [validFiles[0]] : fileStores[storeKey];\n        }\n\n        renderFileList(storeKey);\n        if (window.revalidateFormIssues) window.revalidateFormIssues(true);\n        notifyVerifyFileChange(storeKey);\n        return true;\n    }\n\n    function removeFileFromStore(storeKey, index) {\n        if (fileStores[storeKey]) {\n            fileStores[storeKey].splice(index, 1);\n            renderFileList(storeKey);\n            if (window.revalidateFormIssues) window.revalidateFormIssues(true);\n            notifyVerifyFileChange(storeKey);\n        }\n    }\n\n    function notifyVerifyFileChange(storeKey) {\n        if (!window.refundVerify) return;\n        if (storeKey === 'attachments' || isMedicalDocsKey(storeKey)) {\n            window.refundVerify.markAttachmentsDirty();\n            return;\n        }\n        const m = \/^invoiceFile(\\d+)$\/.exec(storeKey);\n        if (m) {\n            window.refundVerify.markServiceDirty(parseInt(m[1], 10));\n        }\n    }\n\n    function appendStoredFilesToFormData(formData) {\n        \/\/ Usu\u0144 pliki z natywnych input\u00f3w (s\u0105 puste bo resetujemy po ka\u017cdym wyborze)\n        \/\/ Dodaj pliki ze store'\u00f3w.\n        \/\/ attachments[] is a single pool fed by EVERY service's medical-documentation zone,\n        \/\/ so it is cleared once here, not per store - clearing it inside the loop would drop\n        \/\/ the files appended by the services visited earlier.\n        formData.delete('attachments[]');\n\n        Object.keys(fileStores).forEach(storeKey => {\n            const files = fileStores[storeKey];\n            if (storeKey === 'attachments' || isMedicalDocsKey(storeKey)) {\n                formData.delete(storeKey);\n                files.forEach(file => {\n                    formData.append('attachments[]', file);\n                });\n            } else {\n                \/\/ Invoice files - pojedyncze pliki\n                formData.delete(storeKey);\n                if (files.length > 0) {\n                    formData.append(storeKey, files[0]);\n                }\n            }\n        });\n    }\n\n    \/\/ Delegowany event listener dla przycisk\u00f3w usuwania plik\u00f3w\n    document.addEventListener('click', function(e) {\n        const removeBtn = e.target.closest('.file-list-item-remove');\n        if (removeBtn) {\n            const storeKey = removeBtn.dataset.store;\n            const index = parseInt(removeBtn.dataset.index);\n            removeFileFromStore(storeKey, index);\n        }\n    });\n\n    function initFileUploads() {\n        document.querySelectorAll('.file-upload-zone').forEach(zone => {\n            \/\/ Pomijamy ju\u017c zainicjalizowane strefy\n            if (zone.dataset.initialized === 'true') return;\n            zone.dataset.initialized = 'true';\n\n            const input = zone.querySelector('input[type=\"file\"]');\n            const initialKey = zone.dataset.uploadFor;\n\n            if (!fileStores[initialKey]) {\n                fileStores[initialKey] = [];\n            }\n\n            \/\/ Dynamiczne odczytywanie klucza i trybu z atrybut\u00f3w\n            function getCurrentKey() { return zone.dataset.uploadFor; }\n            function isMultiple() { return zone.dataset.multiple === 'true'; }\n\n            \/\/ Klik na stref\u0119 otwiera dialog plik\u00f3w\n            zone.addEventListener('click', function(e) {\n                if (e.target.closest('.file-list-item-remove')) return;\n                input.click();\n            });\n\n            \/\/ Obs\u0142uga wyboru plik\u00f3w\n            input.addEventListener('change', function() {\n                if (this.files.length > 0) {\n                    addFilesToStore(getCurrentKey(), this.files, isMultiple());\n                }\n                this.value = '';\n            });\n\n            \/\/ Drag & drop\n            zone.addEventListener('dragover', function(e) {\n                e.preventDefault();\n                this.classList.add('dragover');\n            });\n\n            zone.addEventListener('dragleave', function(e) {\n                e.preventDefault();\n                this.classList.remove('dragover');\n            });\n\n            zone.addEventListener('drop', function(e) {\n                e.preventDefault();\n                this.classList.remove('dragover');\n                if (e.dataTransfer.files.length > 0) {\n                    addFilesToStore(getCurrentKey(), e.dataTransfer.files, isMultiple());\n                }\n            });\n        });\n    }\n\n\t\/* \u2500\u2500 Kod pocztowy i data \u015bwiadczenia \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n\n    function validatePostalCode(postalCode) {\n        \/\/ Format kodu pocztowego: 00-000\n        return \/^\\d{2}-\\d{3}$\/.test(postalCode);\n    }\n\n    function setupServicePostalCodeValidation() {\n        document.querySelectorAll('.servicePostalCode').forEach(input => {\n            \/\/ Usuwamy poprzednie event listenery \u017ceby unikn\u0105\u0107 duplikacji\n            input.removeEventListener('input', postalCodeInputHandler);\n            input.removeEventListener('blur', postalCodeBlurHandler);\n            \n            \/\/ Dodajemy nowe event listenery\n            input.addEventListener('input', postalCodeInputHandler);\n            input.addEventListener('blur', postalCodeBlurHandler);\n        });\n    }\n    \n    \/\/ Funkcja do dodawania event listener\u00f3w dla dat \u015bwiadcze\u0144\n    function setupServiceDateValidation() {\n        document.querySelectorAll('.service-date').forEach(input => {\n            \/\/ Usuwamy poprzednie event listenery \u017ceby unikn\u0105\u0107 duplikacji\n            input.removeEventListener('blur', serviceDateBlurHandler);\n            \n            \/\/ Dodajemy nowe event listenery\n            input.addEventListener('blur', serviceDateBlurHandler);\n        });\n    }\n    \n    function serviceDateBlurHandler() {\n        const date = this.value;\n        const errorElement = this.parentElement.querySelector('.service-date-error');\n\n        if (date && (!validateDateNotFromFuture(date) || !validateDateWithin3Years(date))) {\n            errorElement.classList.remove('hidden');\n            this.classList.add('border-red-500');\n        } else {\n            errorElement.classList.add('hidden');\n            this.classList.remove('border-red-500');\n        }\n    }\n    \n    function postalCodeInputHandler(e) {\n        let value = e.target.value.replace(\/[^0-9-]\/g, '');\n        \n        \/\/ Automatycznie dodajemy my\u015blnik po dw\u00f3ch cyfrach, je\u015bli go nie ma\n        if (value.length === 2 && !value.includes('-')) {\n            value += '-';\n        }\n        \n        \/\/ Usuwamy wszystkie my\u015blniki poza pierwszym po 2 cyfrach\n        if (value.length > 3) {\n            const firstPart = value.substring(0, 3); \/\/ Pierwsze 2 cyfry + my\u015blnik\n            const secondPart = value.substring(3).replace(\/-\/g, ''); \/\/ Reszta bez my\u015blnik\u00f3w\n            value = firstPart + secondPart;\n        }\n        \n        \/\/ Ograniczamy d\u0142ugo\u015b\u0107 do 6 znak\u00f3w (2 cyfry + my\u015blnik + 3 cyfry)\n        value = value.substring(0, 6);\n        \n        \/\/ Aktualizujemy warto\u015b\u0107 pola\n        e.target.value = value;\n    }\n    \n    function postalCodeBlurHandler() {\n        const postalCode = this.value;\n        const errorElement = this.parentElement.querySelector('.servicePostalCodeError');\n        \n        if (!validatePostalCode(postalCode)) {\n            errorElement.classList.remove('hidden');\n            this.classList.add('border-red-500');\n        } else {\n            errorElement.classList.add('hidden');\n            this.classList.remove('border-red-500');\n        }\n    }\n    \n    function applyDateBoundsToAllServiceDates() {\n        document.querySelectorAll('.service-date').forEach(applyDateBoundsToServiceDate);\n    }\n\n\t\/* \u2500\u2500 Rebinding walidator\u00f3w po dodaniu \u015bwiadczenia \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n\n    afterSetup(function() {\n        \/\/ Inicjalizacja walidacji kod\u00f3w pocztowych plac\u00f3wek\n        setupServicePostalCodeValidation();\n        \/\/ Inicjalizacja walidacji kwot\n        setupAmountValidation();\n        \/\/ Inicjalizacja walidacji numer\u00f3w faktur\n        setupInvoiceNumberValidation();\n        \/\/ Inicjalizacja walidacji dat \u015bwiadcze\u0144\n        setupServiceDateValidation();\n\n        applyDateBoundsToAllServiceDates();\n\n        \/\/ Dodajemy event listener do przycisku dodawania nowego \u015bwiadczenia\n        document.getElementById('addService').addEventListener('click', function() {\n            \/\/ Po dodaniu nowego \u015bwiadczenia czekamy chwil\u0119, a\u017c DOM si\u0119 zaktualizuje\n            setTimeout(function() {\n                setupServicePostalCodeValidation();\n                setupAmountValidation();\n                setupInvoiceNumberValidation();\n                setupServiceDateValidation();\n                applyDateBoundsToAllServiceDates();\n                initFileUploads();\n            }, 100);\n        });\n        \n        \/\/ Wywo\u0142ujemy aktualizacj\u0119 numeracji przy za\u0142adowaniu strony\n        updateServiceNumbers();\n        \/\/ Wywo\u0142ujemy aktualizacj\u0119 widoczno\u015bci przycisk\u00f3w przy za\u0142adowaniu strony\n        updateRemoveButtonsVisibility();\n    });\n\n\t\/* \u2500\u2500 Kwota i nr faktury \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n\n    function validateAmount(amount) {\n        \/\/ Akceptujemy liczby z przecinkiem lub kropk\u0105\n        return \/^(\\d+)([\\.,]\\d{1,2})?$\/.test(amount);\n    }\n    \n    \/\/ Funkcja do dodawania event listener\u00f3w dla p\u00f3l kwot\n    function setupAmountValidation() {\n        document.querySelectorAll('.amount-input').forEach(input => {\n            \/\/ Usuwamy poprzednie event listenery \u017ceby unikn\u0105\u0107 duplikacji\n            input.removeEventListener('input', amountInputHandler);\n            input.removeEventListener('blur', amountBlurHandler);\n            \n            \/\/ Dodajemy nowe event listenery\n            input.addEventListener('input', amountInputHandler);\n            input.addEventListener('blur', amountBlurHandler);\n        });\n    }\n    \n    function amountInputHandler(e) {\n        \/\/ Pozwalamy tylko na cyfry, kropk\u0119 i przecinek\n        let value = e.target.value.replace(\/[^0-9.,]\/g, '');\n        \n        \/\/ Ograniczamy do jednego separatora dziesi\u0119tnego\n        let dotIndex = value.indexOf('.');\n        let commaIndex = value.indexOf(',');\n        \n        if (dotIndex !== -1 && commaIndex !== -1) {\n            \/\/ Je\u015bli s\u0105 oba separatory, usuwamy drugi\n            if (dotIndex < commaIndex) {\n\t\t\t\/\/> this comment is used to circumvent the https:\/\/core.trac.wordpress.org\/ticket\/43785 bug\n                value = value.replace(',', '');\n            } else {\n                value = value.replace('.', '');\n            }\n        }\n        \n        \/\/ Aktualizujemy warto\u015b\u0107 pola\n        e.target.value = value;\n    }\n    \n    function amountBlurHandler() {\n        const amount = this.value;\n        const errorElement = this.parentElement.querySelector('.amount-error');\n        \n        if (!validateAmount(amount)) {\n            errorElement.classList.remove('hidden');\n            this.classList.add('border-red-500');\n        } else {\n            errorElement.classList.add('hidden');\n            this.classList.remove('border-red-500');\n            \n            \/\/ Zamieniamy przecinek na kropk\u0119, aby zapewni\u0107 poprawny format dla API\n            this.value = amount.replace(',', '.');\n        }\n    }\n\n    \/\/ Funkcja do walidacji d\u0142ugo\u015bci numeru faktury\/rachunku\n    function setupInvoiceNumberValidation() {\n        document.querySelectorAll('.invoice-number').forEach(input => {\n            \/\/ Usuwamy poprzednie event listenery \u017ceby unikn\u0105\u0107 duplikacji\n            input.removeEventListener('input', invoiceNumberInputHandler);\n            \n            \/\/ Dodajemy nowe event listenery\n            input.addEventListener('input', invoiceNumberInputHandler);\n        });\n    }\n    \n    function invoiceNumberInputHandler(e) {\n        let value = e.target.value;\n        const errorElement = e.target.nextElementSibling;\n        \n        \/\/ Sprawdzamy d\u0142ugo\u015b\u0107\n        if (value.length > 50) {\n            \/\/ Przycinamy warto\u015b\u0107 do 50 znak\u00f3w\n            value = value.substring(0, 50);\n            e.target.value = value;\n            \n            \/\/ Pokazujemy b\u0142\u0105d\n            errorElement.classList.remove('hidden');\n            e.target.classList.add('border-red-500');\n        } else {\n            \/\/ Ukrywamy b\u0142\u0105d\n            errorElement.classList.add('hidden');\n            e.target.classList.remove('border-red-500');\n        }\n    }\n\n\t\/* \u2500\u2500 RPWDL \u2014 weryfikacja plac\u00f3wki po NIP \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n\n    const RPWDL_CHECK_ENDPOINT = '\/api\/public\/rpwdl\/check';\n    \/\/ 4s covers the backend's worst-case CeZ chain (~3s total budget per the backend\n    \/\/ handoff) plus a buffer for slow networks. Lookup is non-blocking for form submit,\n    \/\/ so timing out longer than this only delays the panel entry, never the user.\n    const RPWDL_LOOKUP_TIMEOUT_MS = 4000;\n    const RPWDL_DEBOUNCE_MS = 400;\n\n    function getServiceIndex(group) {\n        if (!group) return -1;\n        const raw = group.getAttribute('data-service-index');\n        const n = parseInt(raw, 10);\n        return isNaN(n) ? -1 : n;\n    }\n\n    function clearRpwdlLookupRules(idx) {\n        formIssues.remove(`warn.service.${idx}.rpwdl.notFound`);\n        formIssues.remove(`warn.service.${idx}.rpwdl.inactive`);\n        formIssues.remove(`success.service.${idx}.rpwdl.ok`);\n    }\n\n    function setNipHint(group, text) {\n        const hint = group.querySelector('.service-nip-hint');\n        if (!hint) return;\n        if (text) {\n            hint.textContent = text;\n            hint.classList.remove('hidden');\n        } else {\n            hint.textContent = '';\n            hint.classList.add('hidden');\n        }\n    }\n\n    function lookupRpwdl(group, nipClean, dateIso) {\n        const idx = getServiceIndex(group);\n        if (idx < 0) return;\n\t\t\/\/> this comment is used to circumvent the https:\/\/core.trac.wordpress.org\/ticket\/43785 bug\n        const n = idx + 1;\n        const nipInput = group.querySelector('.service-nip');\n        if (!nipInput) return;\n\n        if (group._rpwdlAbort) {\n            try { group._rpwdlAbort.abort(); } catch (e) { \/* ignored *\/ }\n        }\n        const controller = new AbortController();\n        \/\/ Both supersede (a newer lookup) and timeout abort the same controller, so the\n        \/\/ fetch catch handler can't tell them apart from err.name alone. Flag timeouts\n        \/\/ explicitly so the catch can promote them to 'error' (clears stuck 'pending'\n        \/\/ and allows retry on the next handleNipChange tick), while a true supersede\n        \/\/ stays silent and lets the newer lookup replace the verdict.\n        controller.timedOut = false;\n        group._rpwdlAbort = controller;\n        const timeoutId = setTimeout(function () {\n            controller.timedOut = true;\n            controller.abort();\n        }, RPWDL_LOOKUP_TIMEOUT_MS);\n\n        \/\/ Composite cache key: a lookup is uniquely identified by (nip, date). Changing\n        \/\/ either invalidates the cached verdict so the user always sees a status that\n        \/\/ matches the date they typed.\n        const lookupKey = nipClean + '|' + dateIso;\n        group.dataset.rpwdlLookupKey = lookupKey;\n        group.dataset.rpwdlLookupStatus = 'pending';\n\n        const baseUrl = (window.TELEMEDI_API_BASE_URL || '').replace(\/\\\/+$\/, '');\n        const params = new URLSearchParams({ nip: nipClean, date: dateIso });\n        const url = baseUrl + RPWDL_CHECK_ENDPOINT + '?' + params.toString();\n\n        fetch(url, { signal: controller.signal })\n            .then(function (res) {\n                if (!res.ok) throw new Error('http ' + res.status);\n                return res.json();\n            })\n            .then(function (data) {\n                clearTimeout(timeoutId);\n                if (group._rpwdlAbort !== controller) return;\n                group._rpwdlAbort = null;\n                if (group.dataset.rpwdlLookupKey !== lookupKey) return;\n\n                const exists = !!(data && (data.exists_rpwdl || data.existsRpwdl));\n                const rawEntries = (data && (data.rpwdl_entries || data.rpwdlEntries));\n                const entries = Array.isArray(rawEntries) ? rawEntries : [];\n                const entry = entries.length > 0 ? entries[0] : null;\n\n                \/\/ Render the service date in Polish DD.MM.YYYY for human-readable warnings.\n                \/\/ dateIso is the ISO YYYY-MM-DD we passed in; cached on the closure.\n                const datePl = dateIso ? dateIso.split('-').reverse().join('.') : '';\n\n                const facilityName = entry ? (entry.name || '') : '';\n                const kind = !exists || !entry\n                    ? 'miss'\n                    : (entry.is_active === false ? 'inactive' : 'active');\n\n                \/\/ Cache the resolved verdict on the group so service add\/remove can replay\n                \/\/ the same entry under a new idx without hitting the network again.\n                group._rpwdlLastVerdict = { lookupKey: lookupKey, kind: kind, facilityName: facilityName, datePl: datePl };\n                group.dataset.rpwdlLookupStatus = kind === 'miss' ? 'miss' : 'hit';\n                applyRpwdlVerdict(group);\n            })\n            .catch(function (err) {\n                clearTimeout(timeoutId);\n                const wasTimeout = controller.timedOut === true;\n                if (group._rpwdlAbort === controller) group._rpwdlAbort = null;\n                if (group.dataset.rpwdlLookupKey !== lookupKey) return;\n                \/\/ AbortError fires in two cases: the user typed a new NIP\/date mid-flight\n                \/\/ (supersede), or the timeout above tripped. Supersede leaves the existing\n                \/\/ entry alone so the new lookup can replace it. Timeout falls through to\n                \/\/ the error branch below to clear the stuck 'pending' status and free the\n                \/\/ (nip,date) key for retry on the next handleNipChange tick.\n                if (err && err.name === 'AbortError' && !wasTimeout) return;\n                if (wasTimeout) {\n                    console.warn('RPWDL lookup timed out for ' + lookupKey);\n                } else {\n                    console.warn('RPWDL lookup failed for ' + lookupKey + ':', err);\n                }\n                group.dataset.rpwdlLookupStatus = 'error';\n                \/\/ Unknown state: clear any stale verdict from an earlier lookup. We make no\n                \/\/ claim either way and the user can still submit if the NIP checksum is valid.\n                group._rpwdlLastVerdict = null;\n                setNipHint(group, '');\n                clearRpwdlLookupRules(getServiceIndex(group));\n            });\n    }\n\n    \/\/ Re-emit the cached RPWDL verdict for `group` under its current service index. Called\n    \/\/ by lookupRpwdl right after a fetch resolves, and by the service add\/remove flow when\n    \/\/ indices shift, so we can rekey formIssues entries without re-fetching from the backend.\n    function applyRpwdlVerdict(group) {\n        const verdict = group && group._rpwdlLastVerdict;\n        if (!verdict) return;\n        const idx = getServiceIndex(group);\n        if (idx < 0) return;\n\t\t\/\/> this comment is used to circumvent the https:\/\/core.trac.wordpress.org\/ticket\/43785 bug\n        const n = idx + 1;\n        const nipInput = group.querySelector('.service-nip');\n        const facilityName = verdict.facilityName;\n        const datePl = verdict.datePl;\n\n        if (verdict.kind === 'miss') {\n            setNipHint(group, '');\n            formIssues.remove(`warn.service.${idx}.rpwdl.inactive`);\n            formIssues.remove(`success.service.${idx}.rpwdl.ok`);\n            formIssues.upsert(`warn.service.${idx}.rpwdl.notFound`, {\n                severity: 'warning',\n                title: `\u015awiadczenie nr ${n}: nie znaleziono plac\u00f3wki o tym numerze NIP w rejestrze RPWDL dla daty wykonania ${datePl}. Sprawd\u017a, czy NIP oraz data wykonania \u015bwiadczenia s\u0105 poprawne.`,\n                section: `\u015awiadczenie ${n}`,\n                bypassGate: true,\n                fieldRef: nipInput\n            });\n            return;\n        }\n\n        formIssues.remove(`warn.service.${idx}.rpwdl.notFound`);\n        setNipHint(group, facilityName ? `Plac\u00f3wka: ${facilityName}` : '');\n\n        if (verdict.kind === 'inactive') {\n            formIssues.remove(`success.service.${idx}.rpwdl.ok`);\n            formIssues.upsert(`warn.service.${idx}.rpwdl.inactive`, {\n                severity: 'warning',\n                title: `\u015awiadczenie nr ${n}: plac\u00f3wka${facilityName ? ` \u201e${facilityName}\u201d` : ''} nie by\u0142a aktywna w rejestrze RPWDL w dniu wykonania \u015bwiadczenia (${datePl}). Sprawd\u017a, czy NIP oraz data wykonania s\u0105 poprawne przed wys\u0142aniem wniosku.`,\n                section: `\u015awiadczenie ${n}`,\n                bypassGate: true,\n                fieldRef: nipInput\n            });\n        } else {\n            formIssues.remove(`warn.service.${idx}.rpwdl.inactive`);\n            formIssues.upsert(`success.service.${idx}.rpwdl.ok`, {\n                severity: 'success',\n                title: `\u015awiadczenie nr ${n}: plac\u00f3wka${facilityName ? ` \u201e${facilityName}\u201d` : ''} by\u0142a aktywna w rejestrze RPWDL w dniu wykonania \u015bwiadczenia (${datePl}).`,\n                section: `\u015awiadczenie ${n}`,\n                bypassGate: true,\n                fieldRef: nipInput\n            });\n        }\n    }\n\n    function setNipInlineError(group, nipInput, hasError) {\n        const errEl = group.querySelector('.service-nip-error');\n        if (!errEl) return;\n        if (hasError) {\n            errEl.classList.remove('hidden');\n            nipInput.classList.add('border-red-500');\n        } else {\n            errEl.classList.add('hidden');\n            nipInput.classList.remove('border-red-500');\n        }\n    }\n\n    function handleNipChange(group, immediate) {\n        const idx = getServiceIndex(group);\n        if (idx < 0) return;\n\t\t\/\/> this comment is used to circumvent the https:\/\/core.trac.wordpress.org\/ticket\/43785 bug\n        const nipInput = group.querySelector('.service-nip');\n        if (!nipInput) return;\n        const nipClean = normalizeNIP(nipInput.value);\n\n        \/\/ Inline NIP error UI: empty value clears the indicator (required-handling\n        \/\/ covers the empty case via formIssues); a non-empty value that fails\n        \/\/ `validateNIP` flips the red border + inline error on. Mirrors the panel\n        \/\/ entry `err.service.${idx}.nip.invalid` evaluated in evalDeterministic.\n        setNipInlineError(group, nipInput, nipClean.length > 0 && !validateNIP(nipClean));\n\n        \/\/ Read the per-service serviceDate (\"Data wykonania *\") so the lookup can ask\n        \/\/ the backend whether the facility was active on the date of \u015bwiadczenie, not\n        \/\/ just today. Both fields must be valid before we hit the network.\n        const dateInput = group.querySelector('.service-date');\n        const dateRaw = dateInput ? dateInput.value : '';\n        const dateIso = isValidIsoDate(dateRaw) ? dateRaw : '';\n\n        if (!nipClean || !validateNIP(nipClean) || !dateIso) {\n            \/\/ Either field missing\/invalid: cancel everything pending and clear any prior\n            \/\/ verdict. We never show a verdict that ignores the date the user typed.\n            if (group._rpwdlAbort) { try { group._rpwdlAbort.abort(); } catch (e) {} group._rpwdlAbort = null; }\n            if (group._rpwdlDebounceTimer) { clearTimeout(group._rpwdlDebounceTimer); group._rpwdlDebounceTimer = null; }\n            group.dataset.rpwdlLookupKey = '';\n            group.dataset.rpwdlLookupStatus = '';\n            group._rpwdlLastVerdict = null;\n            setNipHint(group, '');\n            clearRpwdlLookupRules(idx);\n            return;\n        }\n\n        if (immediate && group._rpwdlDebounceTimer) {\n            clearTimeout(group._rpwdlDebounceTimer);\n            group._rpwdlDebounceTimer = null;\n        }\n\n        const lookupKey = nipClean + '|' + dateIso;\n        if (group.dataset.rpwdlLookupKey === lookupKey && group.dataset.rpwdlLookupStatus && group.dataset.rpwdlLookupStatus !== 'error') {\n            return;\n        }\n\n        if (immediate) {\n            lookupRpwdl(group, nipClean, dateIso);\n        } else {\n            if (group._rpwdlDebounceTimer) clearTimeout(group._rpwdlDebounceTimer);\n            group._rpwdlDebounceTimer = setTimeout(function () {\n                group._rpwdlDebounceTimer = null;\n                lookupRpwdl(group, nipClean, dateIso);\n            }, RPWDL_DEBOUNCE_MS);\n        }\n    }\n\n    function wireRpwdlLookup() {\n        const servicesContainer = document.getElementById('servicesContainer');\n        if (!servicesContainer) return;\n\n        servicesContainer.addEventListener('input', function (e) {\n            const target = e.target;\n            if (!target || !target.classList) return;\n            const group = target.closest('.service-group');\n            if (!group) return;\n            if (target.classList.contains('service-nip')) {\n                \/\/ Strip non-digits in place and cap at 10 digits, so a paste like\n                \/\/ \"123-456-32-18\" (12 chars) is not truncated by the input maxlength before\n                \/\/ validation can normalize it.\n                const cleaned = normalizeNIP(target.value).slice(0, 10);\n                if (target.value !== cleaned) {\n                    target.value = cleaned;\n                }\n                handleNipChange(group, false);\n            } else if (target.classList.contains('service-date')) {\n                \/\/ Service-date edits also refire the RPWDL check, since the verdict\n                \/\/ depends on (NIP, date). Debounced path so partial-typing in a text-mode\n                \/\/ date input does not spam the network.\n                handleNipChange(group, false);\n            }\n        });\n\n        \/\/ <input type=\"date\"> commits via 'change', not 'blur', when picked from a date\n        \/\/ picker. Treat that as the \"user committed\" moment and fire immediately.\n        servicesContainer.addEventListener('change', function (e) {\n            const target = e.target;\n            if (!target || !target.classList) return;\n            if (!target.classList.contains('service-date')) return;\n            const group = target.closest('.service-group');\n            if (!group) return;\n            handleNipChange(group, true);\n        });\n\n        servicesContainer.addEventListener('blur', function (e) {\n            const target = e.target;\n            if (!target || !target.classList) return;\n            if (!target.classList.contains('service-nip')) return;\n            const group = target.closest('.service-group');\n            if (!group) return;\n            handleNipChange(group, true);\n        }, true);\n    }\n\n\t\/* \u2500\u2500 Krok 3: dane z pierwotnego wniosku (read-only) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n\n\t\/\/ Prefilled from GET \/api\/public\/refund\/returning-request\/draft after OTP verification\n\t\/\/ (see loadDraft). No patient data is baked into the page \u2014 the snapshot is fetched live\n\t\/\/ with the session token, and renderClaimSummary tolerates missing keys (renders blanks).\n\tconst SUMMARY_FIELDS = {\n\t\troFirstName: 'firstName',\n\t\troLastName: 'lastName',\n\t\troPesel: 'pesel',\n\t\troBirthDate: 'birthDate',\n\t\troContactNumber: 'contactNumber',\n\t\troEmail: 'email',\n\t\troInsuredPerson: 'insuredPerson',\n\t\troInsuredPesel: 'insuredPesel',\n\t\troStreet: 'street',\n\t\troHouseNumber: 'houseNumber',\n\t\troApartmentNumber: 'apartmentNumber',\n\t\troPostalCode: 'postalCode',\n\t\troCity: 'city',\n\t\troBank: 'bank',\n\t\troAccountOwner: 'accountOwner',\n\t\troAccountNumber: 'accountNumber',\n\t\troProductType: 'productType',\n\t\troPolicyNumber: 'policyNumber'\n\t};\n\n\tfunction formatDatePl(iso) {\n\t\t\/\/ The API speaks ISO; the summary reads better as DD.MM.RRRR.\n\t\treturn \/^\\d{4}-\\d{2}-\\d{2}$\/.test(iso) ? iso.split('-').reverse().join('.') : iso;\n\t}\n\n\tfunction formatAccountNumber(value) {\n\t\treturn String(value).replace(\/\\s+\/g, '').replace(\/(.{4})\/g, '$1 ').trim();\n\t}\n\n\tfunction renderClaimSummary(claim) {\n\t\tObject.keys(SUMMARY_FIELDS).forEach(function (id) {\n\t\t\tconst el = document.getElementById(id);\n\t\t\tif (!el) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tlet value = claim[SUMMARY_FIELDS[id]];\n\t\t\tif (SUMMARY_FIELDS[id] === 'birthDate') {\n\t\t\t\tvalue = formatDatePl(value);\n\t\t\t}\n\t\t\tif (SUMMARY_FIELDS[id] === 'accountNumber') {\n\t\t\t\tvalue = formatAccountNumber(value);\n\t\t\t}\n\t\t\t\/\/ textContent, never innerHTML \u2014 this is claim data, not markup.\n\t\t\tel.textContent = value || '';\n\t\t});\n\t}\n\n\t\/* \u2500\u2500 Krok 3: zgody i wysy\u0142ka \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n\n\tconst submitButton = document.getElementById('submitButton');\n\tconst submitLoader = document.getElementById('loader');\n\tconst requiredConsents = document.querySelectorAll('.consent-checkbox input[type=\"checkbox\"][required]');\n\n\t\/\/ Re-entrancy guard: locks the submit while a request is in flight so a\n\t\/\/ double-click (or a second submit event) can't fire two POSTs \/ replay the token.\n\tlet submitInFlight = false;\n\n\tfunction allConsentsChecked() {\n\t\treturn Array.prototype.every.call(requiredConsents, function (cb) {\n\t\t\treturn cb.checked;\n\t\t});\n\t}\n\n\t\/\/ There is no \"Weryfikuj wniosek\" step here, so the consents alone gate submit.\n\tfunction updateSubmitAvailability() {\n\t\tconst ready = allConsentsChecked();\n\t\tsubmitButton.disabled = !ready;\n\t\tsubmitButton.classList.toggle('opacity-50', !ready);\n\t\tsubmitButton.classList.toggle('cursor-not-allowed', !ready);\n\t}\n\n\tArray.prototype.forEach.call(requiredConsents, function (cb) {\n\t\tcb.addEventListener('change', updateSubmitAvailability);\n\t});\n\n\t\/\/ Ported verbatim from nowy-wniosek.html (2260-2284): a required upload zone with an\n\t\/\/ empty file store blocks submit and turns red.\n\tfunction hasMissingRequiredFiles() {\n\t\tlet hasMissingFiles = false;\n\n\t\tdocument.querySelectorAll('.file-upload-zone').forEach(zone => {\n\t\t\tconst storeKey = zone.dataset.uploadFor;\n\t\t\tconst input = zone.querySelector('input[type=\"file\"]');\n\t\t\tconst files = fileStores[storeKey] || [];\n\t\t\tconst isRequired = input && (input.dataset.wasRequired === 'true' || input.hasAttribute('required'));\n\n\t\t\t\/\/ Sprawd\u017a czy pole jest widoczne (nie ukryte przez warunki)\n\t\t\tconst container = zone.closest('.hidden');\n\t\t\tif (container) return;\n\n\t\t\tif (isRequired && files.length === 0) {\n\t\t\t\thasMissingFiles = true;\n\t\t\t\tzone.style.borderColor = '#ef4444';\n\t\t\t} else {\n\t\t\t\tzone.style.borderColor = '';\n\t\t\t}\n\t\t});\n\n\t\treturn hasMissingFiles;\n\t}\n\n\tfunction setSubmitBusy(busy) {\n\t\tsubmitInFlight = busy;\n\t\tsubmitButton.disabled = busy;\n\t\tsubmitButton.setAttribute('aria-busy', busy ? 'true' : 'false');\n\t\tif (submitLoader) {\n\t\t\tsubmitLoader.classList.toggle('show', busy);\n\t\t}\n\t}\n\n\tfunction handleFinalSubmit() {\n\t\tif (submitInFlight) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!allConsentsChecked()) {\n\t\t\tArray.prototype.forEach.call(requiredConsents, function (cb) {\n\t\t\t\tif (!cb.checked) {\n\t\t\t\t\tcb.closest('.consent-checkbox').classList.add('consent-error');\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tif (hasMissingRequiredFiles()) {\n\t\t\tshowModal('error', 'Brak wymaganych plik\u00f3w', 'Dodaj wymagane pliki (faktury\/rachunki) przed wys\u0142aniem wniosku.');\n\t\t\treturn;\n\t\t}\n\n\t\tif (!document.getElementById('topUpForm').reportValidity()) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!sessionToken) {\n\t\t\tshowModal('error', 'Sesja wygas\u0142a', 'Zweryfikuj wniosek jeszcze raz, aby go wys\u0142a\u0107.');\n\t\t\treturn;\n\t\t}\n\n\t\t\/\/ Wszystkie walidacje przesz\u0142y \u2014 poka\u017c modal potwierdzenia (parytet z nowy-wniosek.html);\n\t\t\/\/ w\u0142a\u015bciwa wysy\u0142ka rusza dopiero po \"Tak, wysy\u0142am wniosek\" (performReturningSubmit).\n\t\tdocument.getElementById('confirmModal').classList.add('show');\n\t\tdocument.body.style.overflow = 'hidden';\n\t}\n\n\tfunction performReturningSubmit() {\n\t\t\/\/ The shared <form> also holds the step-1\/2 fields (claimNumber, claimPesel, otpCode),\n\t\t\/\/ and the read-only identity is rendered as text (not inputs) \u2014 so FormData carries only\n\t\t\/\/ the fresh step-3 data. The submit endpoint ignores every unknown key, enforcing AC2\n\t\t\/\/ server-side regardless of what the form emits.\n\t\tconst formData = new FormData(form);\n\t\tappendStoredFilesToFormData(formData);\n\n\t\tsetSubmitBusy(true);\n\n\t\tconst baseUrl = (window.TELEMEDI_API_BASE_URL || '').replace(\/\\\/+$\/, '');\n\t\tfetch(baseUrl + SUBMIT_ENDPOINT, {\n\t\t\tmethod: 'POST',\n\t\t\theaders: { 'Authorization': 'Bearer ' + sessionToken },\n\t\t\tbody: formData\n\t\t})\n\t\t\t.then(function (res) {\n\t\t\t\tif (res.status === 200) {\n\t\t\t\t\treturn res.json().then(function (b) { return { status: 200, body: b }; });\n\t\t\t\t}\n\t\t\t\treturn { status: res.status, body: null };\n\t\t\t})\n\t\t\t.then(function (result) {\n\t\t\t\tif (result.status === 200 && result.body && result.body.issueNumber) {\n\t\t\t\t\t\/\/ Single-use: drop the token so a back-nav or refresh cannot replay it.\n\t\t\t\t\tsessionToken = null;\n\t\t\t\t\t\/\/ Keep the button locked (submitInFlight stays true) \u2014 the customer\n\t\t\t\t\t\/\/ gets an explicit confirmation with their case number, and closing\n\t\t\t\t\t\/\/ the modal takes them to the success page.\n\t\t\t\t\tshowModal(\n\t\t\t\t\t\t'success',\n\t\t\t\t\t\t'Wniosek wys\u0142any',\n\t\t\t\t\t\t'Dzi\u0119kujemy. Twoja dokumentacja zosta\u0142a wys\u0142ana do zespo\u0142u refundacji. Numer Twojej sprawy: ' + result.body.issueNumber + '.',\n\t\t\t\t\t\t\/\/ No success slug injected? The modal above already confirmed the\n\t\t\t\t\t\t\/\/ submission and showed the case number, so simply stay put.\n\t\t\t\t\t\tfunction () {\n\t\t\t\t\t\t\tconst target = successUrl();\n\t\t\t\t\t\t\tif (target) {\n\t\t\t\t\t\t\t\twindow.location.href = target;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tsetSubmitBusy(false);\n\t\t\t\tif (result.status === 401) {\n\t\t\t\t\tshowModal('error', 'Sesja wygas\u0142a', MSG.sessionExpired);\n\t\t\t\t} else if (result.status === 422) {\n\t\t\t\t\tshowModal('error', 'Uzupe\u0142nij dane', 'Sprawd\u017a poprawno\u015b\u0107 \u015bwiadcze\u0144, faktur i wymaganych zg\u00f3d.');\n\t\t\t\t} else if (result.status === 429) {\n\t\t\t\t\tshowModal('error', 'Zbyt wiele pr\u00f3b', MSG.otpRateLimited);\n\t\t\t\t} else {\n\t\t\t\t\tshowModal('error', 'B\u0142\u0105d wysy\u0142ki', MSG.submitError);\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch(function () {\n\t\t\t\tsetSubmitBusy(false);\n\t\t\t\tshowModal('error', 'B\u0142\u0105d wysy\u0142ki', MSG.submitError);\n\t\t\t});\n\t}\n\n\tafterSetup(function () {\n\t\twireRpwdlLookup();\n\t\tupdateSubmitAvailability();\n\n\t\t\/\/ Modal potwierdzenia wysy\u0142ki\n\t\tdocument.getElementById('confirmBackBtn').addEventListener('click', function () {\n\t\t\tdocument.getElementById('confirmModal').classList.remove('show');\n\t\t\tdocument.body.style.overflow = '';\n\t\t});\n\t\tdocument.getElementById('confirmModal').addEventListener('click', function (e) {\n\t\t\tif (e.target === this) {\n\t\t\t\tthis.classList.remove('show');\n\t\t\t\tdocument.body.style.overflow = '';\n\t\t\t}\n\t\t});\n\t\tdocument.getElementById('confirmSubmitBtn').addEventListener('click', function () {\n\t\t\tdocument.getElementById('confirmModal').classList.remove('show');\n\t\t\tdocument.body.style.overflow = '';\n\t\t\tperformReturningSubmit();\n\t\t});\n\n\t\t\/\/ The anchors ship without an href; hide them outright when WordPress did\n\t\t\/\/ not inject the slug, so nobody is offered a link that goes nowhere.\n\t\t['newClaimLink', 'newClaimNoticeLink'].forEach(function (id) {\n\t\t\tconst el = document.getElementById(id);\n\t\t\tif (!el) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst target = newClaimUrl();\n\t\t\tif (target) {\n\t\t\t\tel.href = target;\n\t\t\t} else {\n\t\t\t\tel.style.display = 'none';\n\t\t\t}\n\t\t});\n\t});\n\n\tupdateStepper();\n\n\tdeferredSetup.forEach(function (fn) {\n\t\tfn();\n\t});\n}\n\nif (document.readyState === 'loading') {\n\tdocument.addEventListener('DOMContentLoaded', initTopUpForm);\n} else {\n\tinitTopUpForm();\n}\n\n<\/script>\n\n\n<script>\n\t\/\/ Last line of defence, in case both copies of the link tag get mangled on paste:\n\t\/\/ the probe checks whether class p-8 yields 2rem of padding and, if it does not,\n\t\/\/ pulls the stylesheet in at runtime.\n\t(function () {\n\t\tvar TAILWIND_URL = 'https:\/\/cdn.jsdelivr.net\/npm\/tailwindcss@2.2.19\/dist\/tailwind.min.css';\n\n\t\tfunction ensureTailwind() {\n\t\t\tvar probe = document.createElement('div');\n\t\t\tprobe.className = 'p-8';\n\t\t\tprobe.style.position = 'absolute';\n\t\t\tprobe.style.visibility = 'hidden';\n\t\t\tdocument.body.appendChild(probe);\n\t\t\tvar pad = window.getComputedStyle(probe).paddingTop;\n\t\t\tprobe.remove();\n\n\t\t\tif (pad === '2rem' || pad === '32px') {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar link = document.createElement('link');\n\t\t\tlink.rel = 'stylesheet';\n\t\t\tlink.href = TAILWIND_URL;\n\t\t\tdocument.head.appendChild(link);\n\t\t}\n\n\t\tif (document.readyState === 'loading') {\n\t\t\tdocument.addEventListener('DOMContentLoaded', ensureTailwind);\n\t\t} else {\n\t\t\tensureTailwind();\n\t\t}\n\t})();\n<\/script>\n\n<script>\n\t\/\/ The CHECK itself waits for the document, not just the DOM work it triggers.\n\t\/\/ WordPress decides where the config script lands relative to this one, so\n\t\/\/ reading the global while parsing could see `undefined` and hide a perfectly\n\t\/\/ working form.\n\t(function () {\n\t\tfunction guardConfig() {\n\t\t\tif (window.TELEMEDI_API_BASE_URL) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdocument.getElementById('form__wrapper').style.display = 'none';\n\t\t\tdocument.getElementById('unavailablePage').classList.add('show');\n\t\t}\n\n\t\tif (document.readyState === 'loading') {\n\t\t\tdocument.addEventListener('DOMContentLoaded', guardConfig);\n\t\t} else {\n\t\t\tguardConfig();\n\t\t}\n\t})();\n<\/script>\n\n<noscript>\n\t<div class=\"bg-red-600 text-white p-4 text-center font-bold mb-4\">\n\t\tUwaga! Ta strona wymaga w\u0142\u0105czonego JavaScript, aby dzia\u0142a\u0107 poprawnie. W\u0142\u0105cz obs\u0142ug\u0119 JavaScript w przegl\u0105darce i od\u015bwie\u017c stron\u0119.\n\t<\/div>\n<\/noscript>\n\n<!-- Customowy modal dla komunikat\u00f3w -->\n<div id=\"customModal\" class=\"custom-modal\">\n    <div class=\"modal-content\">\n        <div class=\"modal-header\">\n            <div id=\"modalIcon\" class=\"modal-icon\"><\/div>\n            <h3 id=\"modalTitle\" class=\"modal-title\"><\/h3>\n        <\/div>\n        <div class=\"modal-body\">\n            <div id=\"modalMessage\" class=\"modal-message\"><\/div>\n        <\/div>\n        <div class=\"modal-footer\">\n            <button id=\"modalCloseBtn\" class=\"modal-close-btn\">Zamknij<\/button>\n        <\/div>\n    <\/div>\n<\/div>\n\n<!-- Modal potwierdzenia usuni\u0119cia \u015bwiadczenia -->\n<div id=\"deleteServiceModal\" class=\"custom-modal\">\n    <div class=\"modal-content\">\n        <div class=\"confirm-modal-body\">\n            <h3>Usun\u0105\u0107 to \u015bwiadczenie?<\/h3>\n            <p>Wszystkie dane wprowadzone w tym \u015bwiadczeniu (kategoria, daty, kwota, faktura) zostan\u0105 usuni\u0119te. Tej operacji nie mo\u017cna cofn\u0105\u0107.<\/p>\n        <\/div>\n        <div class=\"confirm-modal-footer\">\n            <button type=\"button\" id=\"deleteServiceCancelBtn\" class=\"confirm-btn confirm-btn-back\">Anuluj<\/button>\n            <button type=\"button\" id=\"deleteServiceConfirmBtn\" class=\"confirm-btn confirm-btn-danger\">Tak, usu\u0144<\/button>\n        <\/div>\n    <\/div>\n<\/div>\n\n<!-- Modal potwierdzenia wys\u0142ania (parytet z nowy-wniosek.html; bez noty o produkcie \u2014 polisy nie mo\u017cna tu zmieni\u0107) -->\n<div id=\"confirmModal\" class=\"custom-modal\">\n    <div class=\"modal-content\">\n        <div class=\"confirm-modal-body\">\n            <h3>Sprawd\u017a wniosek przed wys\u0142aniem<\/h3>\n            <p>Upewnij si\u0119, \u017ce wszystkie dane s\u0105 poprawne.<\/p>\n            <div class=\"confirm-modal-note confirm-modal-note--warn\">\n                <p class=\"confirm-note-title\">B\u0142\u0119dne dane wyd\u0142u\u017c\u0105 weryfikacj\u0119<\/p>\n                <p>Nieprawid\u0142owe lub niekompletne informacje (np. dane plac\u00f3wki, dane \u015bwiadczenia, za\u0142\u0105czone faktury) mog\u0105 znacznie op\u00f3\u017ani\u0107 rozpatrzenie wniosku.<\/p>\n            <\/div>\n        <\/div>\n        <div class=\"confirm-modal-footer\">\n            <button type=\"button\" id=\"confirmBackBtn\" class=\"confirm-btn confirm-btn-back\">Wr\u00f3\u0107 i sprawd\u017a<\/button>\n            <button type=\"button\" id=\"confirmSubmitBtn\" class=\"confirm-btn confirm-btn-submit\">Tak, wysy\u0142am wniosek<\/button>\n        <\/div>\n    <\/div>\n<\/div>\n\n<!-- Strona niedost\u0119pna (gdy brak konfiguracji API) -->\n<div id=\"unavailablePage\" class=\"unavailable-page\">\n\t<div class=\"unavailable-card\">\n\t\t<h1 class=\"unavailable-page-title\">Uzupe\u0142nij dokumentacj\u0119 wniosku<\/h1>\n\t\t<div class=\"unavailable-icon\">\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\">\n\t\t\t\t<path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 9v3.75m9-.75a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 3.75h.008v.008H12v-.008Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/div>\n\t\t<h2>Strona chwilowo niedost\u0119pna<\/h2>\n\t\t<p>Formularz uzupe\u0142nienia dokumentacji jest w tej chwili niedost\u0119pny. Przepraszamy za utrudnienia.<\/p>\n\t\t<div class=\"unavailable-divider\"><\/div>\n\t\t<p class=\"unavailable-hint\">Spr\u00f3buj ponownie za kilka minut.<\/p>\n\t<\/div>\n<\/div>\n\n<div id=\"form__wrapper\" class=\"p-8 flex justify-center min-h-screen\">\n\t<!-- method=\"post\" is a safety net, not a real target: the submit handler always\n\t     preventDefault()s. Without it a broken script would fall back to a native GET\n\t     and put the claim number and PESEL in the query string, hence in the server\n\t     log, the browser history and the Referer header. -->\n\t<form id=\"topUpForm\" method=\"post\" novalidate class=\"w-full max-w-3xl\">\n\t\t<div class=\"flex justify-center mb-6\">\n\t\t\t<img decoding=\"async\" src=\"https:\/\/telemedi.com\/wp-content\/themes\/telemedico-home-page\/src\/icons\/telemedi.svg\"\n\t\t\t     alt=\"Telemedi Logo\"\n\t\t\t     class=\"h-12\">\n\t\t<\/div>\n\n\t\t<h1 class=\"text-2xl font-bold mb-4 text-center\">Uzupe\u0142nij wniosek o refundacj\u0119<\/h1>\n\n\t\t<p class=\"text-gray-700 mb-6 text-center\">\n\t\t\tMasz ju\u017c z\u0142o\u017cony wniosek refundacyjny? Zweryfikuj go poni\u017cej, a nast\u0119pnie do\u0142\u0105cz brakuj\u0105c\u0105 dokumentacj\u0119 \u2014 bez wype\u0142niania ca\u0142ego formularza od nowa.\n\t\t<\/p>\n\n\t\t<ol class=\"stepper\" aria-label=\"Post\u0119p uzupe\u0142niania dokumentacji\">\n\t\t\t<li class=\"stepper-step is-active\" data-step=\"1\" aria-current=\"step\">\n\t\t\t\t<span class=\"stepper-badge\" aria-hidden=\"true\">1<\/span>\n\t\t\t\t<span class=\"stepper-label\">Weryfikacja wniosku<\/span>\n\t\t\t<\/li>\n\t\t\t<li class=\"stepper-step is-locked\" data-step=\"2\">\n\t\t\t\t<span class=\"stepper-badge\" aria-hidden=\"true\">2<\/span>\n\t\t\t\t<span class=\"stepper-label\">Kod potwierdzenia<\/span>\n\t\t\t<\/li>\n\t\t\t<li class=\"stepper-step is-locked\" data-step=\"3\">\n\t\t\t\t<span class=\"stepper-badge\" aria-hidden=\"true\">3<\/span>\n\t\t\t\t<span class=\"stepper-label\">Dokumentacja<\/span>\n\t\t\t<\/li>\n\t\t<\/ol>\n\n\t\t<!-- \u2500\u2500 Krok 1: identyfikacja wniosku \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n\t\t<section id=\"step1\" class=\"wizard-step form-section is-active\" data-step=\"1\" tabindex=\"-1\">\n\t\t\t<h2 class=\"form-section-title has-subtitle\">Zweryfikuj sw\u00f3j wniosek<\/h2>\n\t\t\t<p class=\"form-section-subtitle\">Podaj numer wniosku oraz PESEL osoby uprawnionej do refundacji.<\/p>\n\n\t\t\t<div class=\"form-grid-2\">\n\t\t\t\t<div>\n\t\t\t\t\t<label for=\"claimNumber\" class=\"block text-gray-700\">Numer wniosku *<\/label>\n\t\t\t\t\t<input type=\"text\" id=\"claimNumber\" name=\"claimNumber\" inputmode=\"numeric\" autocomplete=\"off\"\n\t\t\t\t\t       maxlength=\"16\" class=\"block w-full border border-gray-300 rounded-md p-2\"\n\t\t\t\t\t       aria-describedby=\"claimNumberHint claimNumberError\" required>\n\t\t\t\t\t<p id=\"claimNumberHint\" class=\"step-hint\">12 cyfr, np. 260528654213<\/p>\n\t\t\t\t\t<p id=\"claimNumberError\" class=\"text-red-500 text-sm mt-1 hidden\">Nieprawid\u0142owy numer wniosku.<\/p>\n\t\t\t\t<\/div>\n\t\t\t\t<div>\n\t\t\t\t\t<label for=\"claimPesel\" class=\"block text-gray-700\">PESEL *<\/label>\n\t\t\t\t\t<input type=\"text\" id=\"claimPesel\" name=\"claimPesel\" inputmode=\"numeric\" autocomplete=\"off\"\n\t\t\t\t\t       maxlength=\"11\" class=\"block w-full border border-gray-300 rounded-md p-2\"\n\t\t\t\t\t       aria-describedby=\"claimPeselError\" required>\n\t\t\t\t\t<p id=\"claimPeselError\" class=\"text-red-500 text-sm mt-1 hidden\">Wprowadzony numer PESEL jest nieprawid\u0142owy.<\/p>\n\t\t\t\t<\/div>\n\t\t\t<\/div>\n\n\t\t\t<div id=\"step1Result\" class=\"mb-4\" aria-live=\"polite\"><\/div>\n\n\t\t\t<div class=\"flex items-center gap-4 flex-wrap\">\n\t\t\t\t<button type=\"submit\" id=\"checkClaimBtn\"\n\t\t\t\t        class=\"bg-green-500 text-white font-bold py-3 px-6 rounded-md hover:bg-green-600 flex items-center gap-2\">\n\t\t\t\t\t<span>Zweryfikuj wniosek<\/span>\n\t\t\t\t\t<span id=\"checkClaimLoader\" class=\"spinner-border\"><\/span>\n\t\t\t\t<\/button>\n\t\t\t\t<a id=\"newClaimLink\"\n\t\t\t\t   class=\"text-blue-500 font-semibold hover:text-blue-600\">\n\t\t\t\t\tChc\u0119 z\u0142o\u017cy\u0107 nowy wniosek\n\t\t\t\t<\/a>\n\t\t\t<\/div>\n\t\t<\/section>\n\n\t\t<!-- \u2500\u2500 Krok 2: kod potwierdzenia (UI, bez backendu) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n\t\t<section id=\"step2\" class=\"wizard-step form-section\" data-step=\"2\" tabindex=\"-1\">\n\t\t\t<h2 class=\"form-section-title has-subtitle\">Wpisz kod potwierdzenia<\/h2>\n\t\t\t<p class=\"form-section-subtitle\">Na numer telefonu podany w oryginalnym wniosku wys\u0142ali\u015bmy kod potwierdzenia<span id=\"otpMaskedPhone\"><\/span><\/p>\n\n\t\t\t<label for=\"otpCode\" class=\"block text-gray-700\">6-cyfrowy kod *<\/label>\n\t\t\t<input type=\"text\" id=\"otpCode\" name=\"otpCode\" inputmode=\"numeric\" autocomplete=\"one-time-code\"\n\t\t\t       maxlength=\"6\" pattern=\"\\d{6}\"\n\t\t\t       class=\"otp-input block w-full border border-gray-300 rounded-md p-2 text-center\"\n\t\t\t       aria-describedby=\"otpHint\">\n\t\t\t<p id=\"otpHint\" class=\"step-hint\">Wpisz 6 cyfr z wiadomo\u015bci SMS.<\/p>\n\t\t\t<p id=\"otpError\" class=\"text-sm text-red-600 mt-2 hidden\" aria-live=\"polite\"><\/p>\n\n\t\t\t<div class=\"mt-4 flex items-center gap-3\">\n\t\t\t\t<button type=\"button\" id=\"verifyOtpBtn\" disabled\n\t\t\t\t        class=\"bg-green-500 text-white font-bold py-3 px-6 rounded-md hover:bg-green-600 flex items-center gap-2 opacity-50 cursor-not-allowed\">\n\t\t\t\t\t<span>Potwierd\u017a kod<\/span>\n\t\t\t\t\t<span id=\"verifyOtpLoader\" class=\"spinner-border\"><\/span>\n\t\t\t\t<\/button>\n\t\t\t\t<button type=\"button\" id=\"resendOtpBtn\" disabled\n\t\t\t\t        class=\"resend-btn text-blue-500 font-semibold hover:text-blue-600\">\n\t\t\t\t\tWy\u015blij kod ponownie <span id=\"resendCooldown\"><\/span>\n\t\t\t\t<\/button>\n\t\t\t<\/div>\n\t\t<\/section>\n\n\t\t<!-- \u2500\u2500 Krok 3: dane z wniosku (read-only) + nowa dokumentacja \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n\t\t<div id=\"step3\" class=\"wizard-step\" data-step=\"3\" tabindex=\"-1\">\n\n\t\t\t<section class=\"form-section\">\n\t\t\t\t<div class=\"readonly-heading\">\n\t\t\t\t\t<h2 class=\"form-section-title has-subtitle\" style=\"margin-bottom:0;\">Dane osoby uprawnionej do Refundacji<\/h2>\n\t\t\t\t\t<span class=\"readonly-badge\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"3\" y=\"11\" width=\"18\" height=\"11\" rx=\"2\"\/><path d=\"M7 11V7a5 5 0 0 1 10 0v4\"\/><\/svg>Tylko do odczytu<\/span>\n\t\t\t\t<\/div>\n\t\t\t\t<p class=\"form-section-subtitle\">Dane pobrane z Twojego pierwotnego wniosku<\/p>\n\t\t\t\t<dl class=\"readonly-grid\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<dt class=\"readonly-label\">Imi\u0119<\/dt>\n\t\t\t\t\t\t<dd class=\"readonly-value\" id=\"roFirstName\"><\/dd>\n\t\t\t\t\t<\/div>\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<dt class=\"readonly-label\">Nazwisko<\/dt>\n\t\t\t\t\t\t<dd class=\"readonly-value\" id=\"roLastName\"><\/dd>\n\t\t\t\t\t<\/div>\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<dt class=\"readonly-label\">PESEL<\/dt>\n\t\t\t\t\t\t<dd class=\"readonly-value\" id=\"roPesel\"><\/dd>\n\t\t\t\t\t<\/div>\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<dt class=\"readonly-label\">Data urodzenia<\/dt>\n\t\t\t\t\t\t<dd class=\"readonly-value\" id=\"roBirthDate\"><\/dd>\n\t\t\t\t\t<\/div>\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<dt class=\"readonly-label\">Numer kontaktowy<\/dt>\n\t\t\t\t\t\t<dd class=\"readonly-value\" id=\"roContactNumber\"><\/dd>\n\t\t\t\t\t<\/div>\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<dt class=\"readonly-label\">Adres e-mail do korespondencji<\/dt>\n\t\t\t\t\t\t<dd class=\"readonly-value\" id=\"roEmail\"><\/dd>\n\t\t\t\t\t<\/div>\n\t\t\t\t\t<div class=\"readonly-field--full\">\n\t\t\t\t\t\t<dt class=\"readonly-label\">Kogo dotyczy zg\u0142oszenie<\/dt>\n\t\t\t\t\t\t<dd class=\"readonly-value\" id=\"roInsuredPerson\"><\/dd>\n\t\t\t\t\t<\/div>\n\t\t\t\t\t<div class=\"readonly-field--full\">\n\t\t\t\t\t\t<dt class=\"readonly-label\">PESEL g\u0142\u00f3wnego ubezpieczonego<\/dt>\n\t\t\t\t\t\t<dd class=\"readonly-value\" id=\"roInsuredPesel\"><\/dd>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/dl>\n\t\t\t<\/section>\n\n\t\t\t<section class=\"form-section\">\n\t\t\t\t<div class=\"readonly-heading\">\n\t\t\t\t\t<h2 class=\"form-section-title\" style=\"margin-bottom:0;\">Adres do korespondencji<\/h2>\n\t\t\t\t\t<span class=\"readonly-badge\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"3\" y=\"11\" width=\"18\" height=\"11\" rx=\"2\"\/><path d=\"M7 11V7a5 5 0 0 1 10 0v4\"\/><\/svg>Tylko do odczytu<\/span>\n\t\t\t\t<\/div>\n\t\t\t\t<dl class=\"readonly-grid\">\n\t\t\t\t\t<div class=\"readonly-field--full\">\n\t\t\t\t\t\t<dt class=\"readonly-label\">Ulica<\/dt>\n\t\t\t\t\t\t<dd class=\"readonly-value\" id=\"roStreet\"><\/dd>\n\t\t\t\t\t<\/div>\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<dt class=\"readonly-label\">Nr domu<\/dt>\n\t\t\t\t\t\t<dd class=\"readonly-value\" id=\"roHouseNumber\"><\/dd>\n\t\t\t\t\t<\/div>\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<dt class=\"readonly-label\">Nr lokalu<\/dt>\n\t\t\t\t\t\t<dd class=\"readonly-value\" id=\"roApartmentNumber\"><\/dd>\n\t\t\t\t\t<\/div>\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<dt class=\"readonly-label\">Kod pocztowy<\/dt>\n\t\t\t\t\t\t<dd class=\"readonly-value\" id=\"roPostalCode\"><\/dd>\n\t\t\t\t\t<\/div>\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<dt class=\"readonly-label\">Miejscowo\u015b\u0107<\/dt>\n\t\t\t\t\t\t<dd class=\"readonly-value\" id=\"roCity\"><\/dd>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/dl>\n\t\t\t<\/section>\n\n\t\t\t<section class=\"form-section\">\n\t\t\t\t<div class=\"readonly-heading\">\n\t\t\t\t\t<h2 class=\"form-section-title\" style=\"margin-bottom:0;\">Dane do wyp\u0142aty<\/h2>\n\t\t\t\t\t<span class=\"readonly-badge\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"3\" y=\"11\" width=\"18\" height=\"11\" rx=\"2\"\/><path d=\"M7 11V7a5 5 0 0 1 10 0v4\"\/><\/svg>Tylko do odczytu<\/span>\n\t\t\t\t<\/div>\n\t\t\t\t<dl class=\"readonly-grid\">\n\t\t\t\t\t<div class=\"readonly-field--full\">\n\t\t\t\t\t\t<dt class=\"readonly-label\">Bank\/Oddzia\u0142<\/dt>\n\t\t\t\t\t\t<dd class=\"readonly-value\" id=\"roBank\"><\/dd>\n\t\t\t\t\t<\/div>\n\t\t\t\t\t<div class=\"readonly-field--full\">\n\t\t\t\t\t\t<dt class=\"readonly-label\">W\u0142a\u015bciciel konta<\/dt>\n\t\t\t\t\t\t<dd class=\"readonly-value\" id=\"roAccountOwner\"><\/dd>\n\t\t\t\t\t<\/div>\n\t\t\t\t\t<div class=\"readonly-field--full\">\n\t\t\t\t\t\t<dt class=\"readonly-label\">Nr rachunku<\/dt>\n\t\t\t\t\t\t<dd class=\"readonly-value\" id=\"roAccountNumber\"><\/dd>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/dl>\n\t\t\t<\/section>\n\n\t\t\t<section class=\"form-section\">\n\t\t\t\t<div class=\"readonly-heading\">\n\t\t\t\t\t<h2 class=\"form-section-title\" style=\"margin-bottom:0;\">Informacje o ubezpieczeniu<\/h2>\n\t\t\t\t\t<span class=\"readonly-badge\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"3\" y=\"11\" width=\"18\" height=\"11\" rx=\"2\"\/><path d=\"M7 11V7a5 5 0 0 1 10 0v4\"\/><\/svg>Tylko do odczytu<\/span>\n\t\t\t\t<\/div>\n\t\t\t\t<dl class=\"readonly-grid\">\n\t\t\t\t\t<div class=\"readonly-field--full\">\n\t\t\t\t\t\t<dt class=\"readonly-label\">Polisa, z kt\u00f3rej ubiegasz si\u0119 o refundacj\u0119<\/dt>\n\t\t\t\t\t\t<dd class=\"readonly-value\" id=\"roProductType\"><\/dd>\n\t\t\t\t\t<\/div>\n\t\t\t\t\t<div class=\"readonly-field--full\">\n\t\t\t\t\t\t<dt class=\"readonly-label\">Nr polisy<\/dt>\n\t\t\t\t\t\t<dd class=\"readonly-value\" id=\"roPolicyNumber\"><\/dd>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/dl>\n\t\t\t<\/section>\n\n\t\t\t<div class=\"mb-5 px-4 py-3 rounded-lg warning-box\">\n\t\t\t\t<p class=\"text-sm warning-box-text\">\n\t\t\t\t\t<span class=\"font-bold\">Powy\u017cszych danych nie mo\u017cna zmieni\u0107 w tym formularzu.<\/span>\n\t\t\t\t\tPochodz\u0105 one z Twojego pierwotnego wniosku. Je\u015bli zmieni\u0142y si\u0119 Twoje dane osobowe,\n\t\t\t\t\tadres, dane do wyp\u0142aty lub chcesz zg\u0142osi\u0107 refundacj\u0119 z innej polisy \u2014 z\u0142\u00f3\u017c nowy wniosek refundacyjny.\n\t\t\t\t<\/p>\n\t\t\t\t<a id=\"newClaimNoticeLink\" class=\"warning-box-link\">\n\t\t\t\t\tZ\u0142\u00f3\u017c nowy wniosek\n\t\t\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M13.5 4.5 21 12m0 0-7.5 7.5M21 12H3\"\/><\/svg>\n\t\t\t\t<\/a>\n\t\t\t<\/div>\n\n\t        <section class=\"form-section\" data-section-index=\"5\">\n\t            <h2 class=\"form-section-title\">\u015awiadczenia zdrowotne oraz dowody poniesionych koszt\u00f3w *<\/h2>\n\t            <div class=\"mb-4 px-4 py-3 rounded-lg info-box\">\n\t                <p class=\"text-sm info-box-text\"><span class=\"font-bold\">Wa\u017cne:<\/span> Plac\u00f3wka medyczna musi by\u0107 zarejestrowana w <span class=\"font-bold\">Rejestrze Podmiot\u00f3w Wykonuj\u0105cych Dzia\u0142alno\u015b\u0107 Lecznicz\u0105 (RPWDL)<\/span>. Sprawd\u017a plac\u00f3wk\u0119 przed wype\u0142nieniem wniosku.<\/p>\n\t                <a href=\"https:\/\/rpwdl2.ezdrowie.gov.pl\/wyszukiwarka\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"info-box-link\">Sprawd\u017a w rejestrze RPWDL\n\t                    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\"\/><polyline points=\"15 3 21 3 21 9\"\/><line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\"\/><\/svg>\n\t                <\/a>\n\t            <\/div>\n\t            <div id=\"servicesContainer\">\n\t                <div class=\"service-group service-subsection\" data-service-index=\"0\">\n\t                    <div class=\"service-subsection-header\">\n\t                        <h3 class=\"service-subsection-title\">\u015awiadczenie 1<\/h3>\n\t                        <button type=\"button\" class=\"remove-service confirm-btn confirm-btn-back remove-service-btn remove-service-btn--hidden\">\n\t                            Usu\u0144 to \u015bwiadczenie\n\t                        <\/button>\n\t                    <\/div>\n\t                    <div class=\"mb-4 service\">\n\t                        <label class=\"block text-gray-700\">Nazwa \u015awiadczenia *<\/label>\n\t                        <select name=\"serviceName[]\" class=\"block w-full border border-gray-300 rounded-md p-2\" required>\n\t                            <option value=\"\">Wybierz kategori\u0119<\/option>\n\t                            <option value=\"Badania obrazowe\">Badania obrazowe<\/option>\n\t                            <option value=\"Us\u0142uga stacjonarna\">Us\u0142uga stacjonarna<\/option>\n\t                            <option value=\"Wizyta domowa\">Wizyta domowa<\/option>\n\t                            <option value=\"Rehabilitacje\">Rehabilitacje<\/option>\n\t                            <option value=\"Sprz\u0119t rehabilitacyjny\">Sprz\u0119t rehabilitacyjny<\/option>\n\t                            <option value=\"Transport\">Transport<\/option>\n\t                            <option value=\"Badania laboratoryjne\">Badania laboratoryjne<\/option>\n\t                            <option value=\"Us\u0142uga Assistance (np. korepetycje)\">Us\u0142uga Assistance (np. korepetycje)<\/option>\n\t                            <option value=\"Us\u0142uga stomatologiczna\">Us\u0142uga stomatologiczna<\/option>\n\t                            <option value=\"Badania medycyny pracy\">Badania medycyny pracy<\/option>\n\t                        <\/select>\n\t                        <div class=\"mt-3 px-4 py-3 rounded-lg warning-box\">\n\t                            <p class=\"text-sm warning-box-text\"><span class=\"font-bold\">Uwaga!<\/span> Wybranie z\u0142ego \u015bwiadczenia spowoduje odrzucenie wniosku refundacyjnego.<\/p>\n\t                        <\/div>\n\t                    <\/div>\n\t                    <div class=\"mb-4 service hidden\">\n\t                        <label class=\"block text-gray-700\">Czy w ramach wizyty lekarskiej by\u0142y realizowane dodatkowe badania? *<\/label>\n\t                        <div class=\"flex gap-4\">\n\t                            <label class=\"flex items-center\">\n\t                                <input type=\"radio\" name=\"additionalTests_0\" value=\"tak\" class=\"mr-2 additional-tests-radio\">\n\t                                <span>Tak<\/span>\n\t                            <\/label>\n\t                            <label class=\"flex items-center\">\n\t                                <input type=\"radio\" name=\"additionalTests_0\" value=\"nie\" class=\"mr-2 additional-tests-radio\">\n\t                                <span>Nie<\/span>\n\t                            <\/label>\n\t                        <\/div>\n\t                    <\/div>\n\t                    <div class=\"mb-4 service additional-tests-details hidden\">\n\t                        <label class=\"block text-gray-700\">Jakie badania by\u0142y realizowane? *<\/label>\n\t                        <input type=\"text\" name=\"examName[]\" class=\"block w-full border border-gray-300 rounded-md p-2\">\n\t                    <\/div>\n\t                    <div class=\"form-grid-2\">\n\t                        <div class=\"service\">\n\t                            <label class=\"block text-gray-700\">Data wykonania *<\/label>\n\t                            <input type=\"date\" name=\"serviceDate[]\" class=\"block w-full border border-gray-300 rounded-md p-2 service-date\" required>\n\t                            <p class=\"service-date-error text-red-500 text-sm mt-1 hidden\">Data wykonania \u015bwiadczenia musi mie\u015bci\u0107 si\u0119 w ostatnich 3 latach.<\/p>\n\t                        <\/div>\n\t                        <div class=\"service\">\n\t                            <label class=\"block text-gray-700\">Nazwa plac\u00f3wki *<\/label>\n\t                            <input type=\"text\" name=\"servicePlace[]\" maxlength=\"200\" class=\"block w-full border border-gray-300 rounded-md p-2\" required>\n\t                        <\/div>\n\t                        <div class=\"service form-grid-2-full\">\n\t                            <label class=\"block text-gray-700\">Adres plac\u00f3wki *<\/label>\n\t                            <input type=\"text\" name=\"serviceAddress[]\" maxlength=\"100\" class=\"block w-full border border-gray-300 rounded-md p-2\" required>\n\t                        <\/div>\n\t                        <div class=\"service\">\n\t                            <label class=\"block text-gray-700\">Kod pocztowy plac\u00f3wki *<\/label>\n\t                            <input type=\"text\" name=\"servicePostalCode[]\" class=\"block w-full border border-gray-300 rounded-md p-2 servicePostalCode\" required>\n\t                            <p class=\"servicePostalCodeError text-red-500 text-sm mt-1 hidden\">Wprowad\u017a poprawny kod pocztowy w formacie 00-000.<\/p>\n\t                        <\/div>\n\t                        <div class=\"service\">\n\t                            <label class=\"block text-gray-700\">Miejscowo\u015b\u0107 plac\u00f3wki *<\/label>\n\t                            <input type=\"text\" name=\"serviceCity[]\" maxlength=\"100\" class=\"block w-full border border-gray-300 rounded-md p-2\" required>\n\t                        <\/div>\n\t                        <div class=\"service form-grid-2-full\">\n\t                            <label class=\"block text-gray-700\">NIP plac\u00f3wki *<\/label>\n\t                            <input type=\"text\" name=\"serviceNIP[]\" class=\"block w-full border border-gray-300 rounded-md p-2 service-nip\" inputmode=\"numeric\" placeholder=\"np. 1234567890\" required>\n\t                            <p class=\"service-nip-error text-red-500 text-sm mt-1 hidden\">Wprowad\u017a poprawny numer NIP (10 cyfr).<\/p>\n\t                            <p class=\"service-nip-hint field-info-hint hidden\"><\/p>\n\t                        <\/div>\n\t                        <div class=\"service\">\n\t                            <label class=\"block text-gray-700\">Kwota (PLN) *<\/label>\n\t                            <input type=\"text\" name=\"amount[]\" maxlength=\"12\" class=\"block w-full border border-gray-300 rounded-md p-2 amount-input\" required>\n\t                            <p class=\"amount-error text-red-500 text-sm mt-1 hidden\">Wprowad\u017a poprawn\u0105 kwot\u0119 (np. 123,45 lub 123.45).<\/p>\n\t                        <\/div>\n\t                        <div class=\"service\">\n\t                            <label class=\"block text-gray-700\">Nr faktury\/rachunku *<\/label>\n\t                            <input type=\"text\" name=\"invoiceNumber[]\" class=\"block w-full border border-gray-300 rounded-md p-2 invoice-number\" maxlength=\"50\" required>\n\t                            <p class=\"invoice-number-error text-red-500 text-sm mt-1 hidden\">Numer faktury\/rachunku nie mo\u017ce przekracza\u0107 50 znak\u00f3w.<\/p>\n\t                        <\/div>\n\t                    <\/div>\n\t                    <div class=\"service\">\n\t                        <label class=\"block text-gray-700 font-bold mb-1\">Za\u0142\u0105cz faktur\u0119\/rachunek *<\/label>\n\t                        <div class=\"file-upload-zone\" data-upload-for=\"invoiceFile0\" data-zone-role=\"invoice\">\n\t                            <input type=\"file\" name=\"invoiceFile0\" accept=\"image\/*,.pdf,.heic,.heif\" data-was-required=\"true\">\n\t                            <p class=\"text-sm text-gray-600\"><span class=\"file-upload-browse\">Wybierz plik<\/span> lub przeci\u0105gnij tutaj<\/p>\n\t                            <div class=\"file-upload-meta\">Zdj\u0119cie lub PDF &middot; maks. 10 MB<\/div>\n\t                        <\/div>\n\t                        <div class=\"file-list\" data-list-for=\"invoiceFile0\" data-list-role=\"invoice\"><\/div>\n\t                    <\/div>\n\t                    <div class=\"service mt-5\">\n\t                        <label class=\"block text-gray-700 mb-1\">Za\u0142\u0105cz dokumentacj\u0119 medyczn\u0105 dotycz\u0105c\u0105 poniesionego kosztu<\/label>\n\t                        <div class=\"file-upload-zone\" data-upload-for=\"medicalDocs0\" data-zone-role=\"medical\" data-multiple=\"true\">\n\t                            <input type=\"file\" name=\"medicalDocs0\" multiple accept=\"image\/*,.pdf,.heic,.heif\">\n\t                            <p class=\"text-sm text-gray-600\"><span class=\"file-upload-browse\">Wybierz dodatkowe pliki<\/span> lub przeci\u0105gnij je tutaj<\/p>\n\t                            <div class=\"file-upload-meta\">Zdj\u0119cia i PDF &middot; maks. 10 MB na plik &middot; mo\u017cna dodawa\u0107 wielokrotnie<\/div>\n\t                        <\/div>\n\t                        <div class=\"file-list\" data-list-for=\"medicalDocs0\" data-list-role=\"medical\"><\/div>\n\t                    <\/div>\n\t                <\/div>\n\t            <\/div>\n\t            <button type=\"button\" id=\"addService\" class=\"bg-green-500 text-white font-bold py-2 px-4 rounded-md hover:bg-green-600\">Dodaj kolejne \u015bwiadczenie<\/button>\n\t        <\/section>\n\t        <section class=\"form-section\" data-section-index=\"6\">\n\t            <h2 class=\"form-section-title\">Zgody i o\u015bwiadczenia<\/h2>\n\t            <div class=\"mb-3\">\n\t                <label class=\"consent-checkbox\">\n\t                    <input type=\"checkbox\" id=\"medicalConsent\" name=\"medicalConsent\" required>\n\t                    <span class=\"consent-check\"><svg viewBox=\"0 0 14 14\" fill=\"none\"><path d=\"M2.5 7.5L5.5 10.5L11.5 3.5\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/><\/svg><\/span>\n\t                    <span class=\"consent-text\">Upowa\u017cniam Telmedicin Sp. z o.o. do dost\u0119pu do dokumentacji medycznej oraz weryfikacji przedstawionej faktury z podmiotem kt\u00f3ry j\u0105 wystawi\u0142 w celu weryfikacji zasadno\u015bci realizacji wniosku o refundacj\u0119 *<\/span>\n\t                <\/label>\n\t            <\/div>\n\n\t            <div class=\"mb-3\">\n\t                <label class=\"consent-checkbox\">\n\t                    <input type=\"checkbox\" id=\"privacyPolicy\" name=\"privacyPolicy\" required>\n\t                    <span class=\"consent-check\"><svg viewBox=\"0 0 14 14\" fill=\"none\"><path d=\"M2.5 7.5L5.5 10.5L11.5 3.5\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/><\/svg><\/span>\n\t                    <span class=\"consent-text\">Je\u017celi prze\u015blesz do nas formularz, administratorem Twoich danych osobowych b\u0119dzie Telmedicin sp. z o.o. Twoje dane b\u0119dziemy przetwarza\u0107 w celu obs\u0142ugi zg\u0142oszenia (jako nasz prawnie uzasadniony interes). Szczeg\u00f3\u0142owe informacje o zasadach ochrony Twoich danych osobowych i przys\u0142uguj\u0105cych Ci prawach znajdziesz w naszej <a href=\"https:\/\/telemedi.com\/pl\/privacy-policy\/\" target=\"_blank\" rel=\"noopener\">Polityce Prywatno\u015bci<\/a>. *<\/span>\n\t                <\/label>\n\t            <\/div>\n\n\t            <div class=\"mb-3\">\n\t                <label class=\"consent-checkbox\">\n\t                    <input type=\"checkbox\" id=\"dataAccuracy\" name=\"dataAccuracy\" required>\n\t                    <span class=\"consent-check\"><svg viewBox=\"0 0 14 14\" fill=\"none\"><path d=\"M2.5 7.5L5.5 10.5L11.5 3.5\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/><\/svg><\/span>\n\t                    <span class=\"consent-text\">O\u015bwiadczam, \u017ce wszystkie dane zawarte w formularzu s\u0105 zgodne ze stanem faktycznym oraz jestem \u015bwiadomy\/\u015bwiadoma odpowiedzialno\u015bci za zeznanie nieprawdy lub zatajenie okoliczno\u015bci, mog\u0105cych mie\u0107 wp\u0142yw na proces likwidacyjny *<\/span>\n\t                <\/label>\n\t            <\/div>\n\n\t            <div>\n\t                <label class=\"consent-checkbox\">\n\t                    <input type=\"checkbox\" id=\"communicationConsent\" name=\"communicationConsent\" required>\n\t                    <span class=\"consent-check\"><svg viewBox=\"0 0 14 14\" fill=\"none\"><path d=\"M2.5 7.5L5.5 10.5L11.5 3.5\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/><\/svg><\/span>\n\t                    <span class=\"consent-text\">O\u015bwiadczam, \u017ce wyra\u017cam zgod\u0119 na przekazywanie informacji dotycz\u0105cych umowy ubezpieczenia z wykorzystaniem \u015brodk\u00f3w porozumiewania si\u0119 na odleg\u0142o\u015b\u0107 na wskazany przeze mnie w formularzu adres email *<\/span>\n\t                <\/label>\n\t            <\/div>\n\t        <\/section>\n\t\t<div class=\"mt-2 mb-2 flex flex-col items-end gap-2\">\n\t\t\t<button type=\"submit\" id=\"submitButton\" disabled title=\"Zaznacz wszystkie zgody i o\u015bwiadczenia, aby wys\u0142a\u0107 wniosek\" class=\"bg-green-500 text-white font-bold py-3 px-6 rounded-md hover:bg-green-600 flex items-center gap-2 opacity-50 cursor-not-allowed\">\n\t\t\t\t<span>Wy\u015blij wniosek<\/span>\n\t\t\t\t<span id=\"loader\" class=\"spinner-border\"><\/span>\n\t\t\t<\/button>\n\t\t<\/div>\n\t\t<\/div>\n\t<\/form>\n<\/div>\n\n<!-- Weryfikacja wniosku - panel walidacji -->\n<div id=\"issuesPanel\" class=\"issues-panel\" role=\"region\" aria-live=\"polite\" aria-label=\"Lista problem\u00f3w w formularzu\">\n    <div class=\"issues-panel-header\">\n        <span class=\"issues-panel-header-icon\" aria-hidden=\"true\">\n            <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\"\/><path d=\"m9 12 2 2 4-4\"\/><\/svg>\n        <\/span>\n        <h2 class=\"issues-panel-header-title\">Weryfikacja wniosku<\/h2>\n        <button type=\"button\" id=\"issuesPanelClose\" class=\"issues-panel-close\" aria-label=\"Zwi\u0144 panel\">\u00d7<\/button>\n    <\/div>\n    <div class=\"issues-panel-chips\">\n        <span id=\"issuesChipError\" class=\"issues-chip issues-chip--error is-hidden\">0 b\u0142\u0119d\u00f3w<\/span>\n        <span id=\"issuesChipWarning\" class=\"issues-chip issues-chip--warning is-hidden\">0 ostrze\u017ce\u0144<\/span>\n        <span id=\"issuesChipSuccess\" class=\"issues-chip issues-chip--success is-hidden\">0 potwierdze\u0144<\/span>\n        <span id=\"issuesChipInfo\" class=\"issues-chip issues-chip--info is-hidden\">0 informacji<\/span>\n    <\/div>\n    <div id=\"issuesPanelBody\" class=\"issues-panel-body\"><\/div>\n    <button type=\"button\" id=\"issuesPanelToggleAll\" class=\"issues-panel-toggle-all\" aria-expanded=\"false\">\n        <span id=\"issuesPanelToggleAllText\">Poka\u017c wszystkie<\/span>\n    <\/button>\n<\/div>\n\n<button type=\"button\" id=\"issuesBadge\" class=\"issues-badge\" aria-label=\"Rozwi\u0144 panel weryfikacji\">\n    <span id=\"issuesBadgeDot\" class=\"issues-badge-dot\"><\/span>\n    <span id=\"issuesBadgeText\">0 b\u0142\u0119d\u00f3w<\/span>\n<\/button>\n\n<div id=\"issuesSuccessPill\" class=\"issues-success-pill\" aria-live=\"polite\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M20 6 9 17l-5-5\"\/><\/svg>\n    <span>Wniosek wygl\u0105da dobrze<\/span>\n<\/div>\n\n<div id=\"issuesSubmitAnnouncement\" aria-live=\"assertive\" role=\"status\" style=\"position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;\"><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Uwaga! Ta strona wymaga w\u0142\u0105czonego JavaScript, aby dzia\u0142a\u0107 poprawnie. W\u0142\u0105cz obs\u0142ug\u0119 JavaScript w przegl\u0105darce i od\u015bwie\u017c stron\u0119. Zamknij Usun\u0105\u0107 to \u015bwiadczenie? Wszystkie dane wprowadzone w tym \u015bwiadczeniu (kategoria, daty, kwota, faktura) zostan\u0105 usuni\u0119te. Tej operacji nie mo\u017cna cofn\u0105\u0107. Anuluj Tak, usu\u0144 Sprawd\u017a wniosek przed wys\u0142aniem Upewnij si\u0119, \u017ce wszystkie dane s\u0105 poprawne. B\u0142\u0119dne dane wyd\u0142u\u017c\u0105 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":22227,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"content-type":"","footnotes":""},"class_list":["post-26073","page","type-page","status-publish","hentry"],"acf":[],"lang":"pl","translations":{"pl":26073},"_links":{"self":[{"href":"https:\/\/telemedi.com\/tm-api\/wp\/v2\/pages\/26073","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/telemedi.com\/tm-api\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/telemedi.com\/tm-api\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/telemedi.com\/tm-api\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/telemedi.com\/tm-api\/wp\/v2\/comments?post=26073"}],"version-history":[{"count":2,"href":"https:\/\/telemedi.com\/tm-api\/wp\/v2\/pages\/26073\/revisions"}],"predecessor-version":[{"id":26076,"href":"https:\/\/telemedi.com\/tm-api\/wp\/v2\/pages\/26073\/revisions\/26076"}],"up":[{"embeddable":true,"href":"https:\/\/telemedi.com\/tm-api\/wp\/v2\/pages\/22227"}],"wp:attachment":[{"href":"https:\/\/telemedi.com\/tm-api\/wp\/v2\/media?parent=26073"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}