{"id":19086,"date":"2026-08-12T13:04:29","date_gmt":"2026-08-12T06:04:29","guid":{"rendered":"https:\/\/staging.vietnamdetox.com\/tong-quan-ve-khoa-nghi-duong\/"},"modified":"2026-08-22T13:54:06","modified_gmt":"2026-08-22T06:54:06","slug":"tong-quan-ve-khoa-nghi-duong","status":"publish","type":"page","link":"https:\/\/staging.vietnamdetox.com\/vi\/tong-quan-ve-khoa-nghi-duong\/","title":{"rendered":"Retreats"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"19086\" class=\"elementor elementor-19086 elementor-19050\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-0c6112f e-flex e-con-boxed e-con e-parent\" data-id=\"0c6112f\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-55437c4 elementor-widget elementor-widget-html\" data-id=\"55437c4\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!--\r\n  Elementor setup\r\n  1. Paste this entire file into ONE Elementor HTML widget.\r\n  2. Paste elementor-retreat-overview-hero.css into that widget's\r\n     Advanced > Custom CSS field.\r\n  3. Keep the parent container full width with zero padding and gap.\r\n\r\n  The hero images, retreat links and retreat names are loaded from the REST API.\r\n  When the dynamic retreat-list widget is on the same page, both widgets share\r\n  one page-level request promise and make only one normal API request together.\r\n-->\r\n\r\n<header class=\"vroh\" id=\"top\" data-vroh-hero=\"\" data-api-url=\"\/wp-json\/retreats\/v1\/all?lang=vi\" aria-label=\"Vietnam Detox retreat overview\">\r\n  <div class=\"vroh__background\" data-vroh-background=\"\" aria-hidden=\"true\">\r\n    <div class=\"vroh__media-status\" data-vroh-media-status=\"\">\u0110ang t\u1ea3i h\u00ecnh \u1ea3nh kh\u00f3a ngh\u1ec9 d\u01b0\u1ee1ng...<\/div>\r\n  <\/div>\r\n\r\n  <div class=\"vroh__overlay\" data-vroh-overlay=\"\" aria-hidden=\"true\"><\/div>\r\n\r\n  <div class=\"vroh__inner\">\r\n    <div class=\"vroh__left\">\r\n      <div class=\"vroh__panel\" data-vroh-panel=\"\">\r\n        <button class=\"vroh__panel-toggle\" data-vroh-panel-toggle=\"\" type=\"button\" aria-label=\"Hide introduction\" aria-expanded=\"true\">\r\n          <span class=\"vroh__panel-toggle-label\" data-vroh-toggle-label=\"\">\u1ea8n h\u1ed9p tho\u1ea1i<\/span>\r\n          <span class=\"vroh__panel-toggle-icon\" data-vroh-toggle-icon=\"\" aria-hidden=\"true\">\u00d7<\/span>\r\n        <\/button>\r\n\r\n        <div class=\"vroh__panel-surface\" data-vroh-panel-surface=\"\">\r\n          <div class=\"vroh__panel-body\" data-vroh-panel-body=\"\">\r\n            <div class=\"vroh__copy\">\r\n              <p class=\"vroh__kicker\">Vietnam Detox \u00b7 C\u00e1c kh\u00f3a ngh\u1ec9 d\u01b0\u1ee1ng nh\u1ecbn \u0103n c\u00f3 h\u01b0\u1edbng d\u1eabn t\u1ea1i Vi\u1ec7t Nam<\/p>\r\n\r\n              <h1 class=\"vroh__title\">\r\n C\u00e1c kh\u00f3a ngh\u1ec9 d\u01b0\u1ee1ng d\u00e0nh cho nh\u1eefng ng\u01b0\u1eddi \u0111ang <span>g\u00e1nh v\u00e1c qu\u00e1 nhi\u1ec1u.<\/span>\r\n              <\/h1>\r\n\r\n              <p class=\"vroh__location\" data-vroh-location=\"\">\r\n Nh\u1ecbn \u0103n theo ph\u01b0\u01a1ng ph\u00e1p Buchinger c\u00f3 h\u01b0\u1edbng d\u1eabn t\u1ea1i Vi\u1ec7t Nam \u2014 h\u00e3y so s\u00e1nh c\u00e1c b\u1ed1i c\u1ea3nh hi\u1ec7n t\u1ea1i c\u1ee7a ch\u00fang t\u00f4i, sau \u0111\u00f3 ch\u1ecdn l\u1ef1a \u0111i\u1ec1u ph\u00f9 h\u1ee3p v\u1edbi t\u00ecnh tr\u1ea1ng hi\u1ec7n t\u1ea1i c\u1ee7a b\u1ea1n.\r\n              <\/p>\r\n\r\n              <p class=\"vroh__lede\">C\u00f9ng m\u1ed9t ph\u01b0\u01a1ng ph\u00e1p \u0111\u00e3 \u0111\u01b0\u1ee3c ch\u1ee9ng minh. Nh\u1eefng c\u00e1ch kh\u00e1c nhau \u0111\u1ec3 cu\u1ed1i c\u00f9ng c\u00f3 th\u1ec3 d\u1eebng l\u1ea1i. <\/p>\r\n\r\n              <p class=\"vroh__support\">\r\n D\u00e0nh cho nh\u1eefng ng\u01b0\u1eddi \u0111ang g\u00e1nh v\u00e1c tr\u00e1ch nhi\u1ec7m v\u1edbi c\u00f4ng vi\u1ec7c, \u0111\u1ed9i ng\u0169 ho\u1eb7c gia \u0111\u00ecnh v\u00e0 \u0111ang d\u1ea7n ki\u1ec7t s\u1ee9c \u0111\u1eb1ng sau v\u1ebb ngo\u00e0i \u1ed5n \u0111\u1ecbnh \u2014 n\u0103m ng\u00e0y c\u00f3 h\u01b0\u1edbng d\u1eabn, trong b\u1ed1i c\u1ea3nh ph\u00f9 h\u1ee3p nh\u1ea5t v\u1edbi b\u1ea1n.\r\n              <\/p>\r\n\r\n              <div class=\"vroh__actions\">\r\n                <a href=\"#retreats\" class=\"vroh__button vroh__button--primary\">So s\u00e1nh c\u00e1c Kh\u00f3a ngh\u1ec9 d\u01b0\u1ee1ng<\/a>\r\n                <a href=\"\/redesign-clickdummy-2026\/faq.html\" class=\"vroh__button vroh__button--outline\">\u0110\u1ecdc C\u00e2u h\u1ecfi th\u01b0\u1eddng g\u1eb7p<\/a>\r\n              <\/div>\r\n\r\n              <nav class=\"vroh__retreat-links\" data-vroh-retreat-links=\"\" aria-label=\"Individual retreat pages\">\r\n                <span class=\"vroh__retreat-status\" data-vroh-retreat-status=\"\">\u0110ang t\u1ea3i c\u00e1c kh\u00f3a ngh\u1ec9 d\u01b0\u1ee1ng...<\/span>\r\n              <\/nav>\r\n            <\/div>\r\n\r\n            <div class=\"vroh__slider-ui\" data-vroh-slider-ui=\"\" aria-label=\"Hero image controls\" hidden=\"\">\r\n              <div class=\"vroh__slider-progress\" aria-hidden=\"true\">\r\n                <span class=\"vroh__slider-progress-fill\" data-vroh-progress=\"\"><\/span>\r\n              <\/div>\r\n              <div class=\"vroh__slider-dots\" data-vroh-dots=\"\" role=\"tablist\" aria-label=\"Hero slides\"><\/div>\r\n            <\/div>\r\n          <\/div>\r\n        <\/div>\r\n      <\/div>\r\n    <\/div>\r\n\r\n    <div class=\"vroh__right\" aria-hidden=\"true\"><\/div>\r\n  <\/div>\r\n<\/header>\r\n\r\n<script>\r\n(function() {\r\n  'use strict';\r\n\r\n  function getSharedRetreatApi() {\r\n    var shared = window.VietnamDetoxRetreatAPI = window.VietnamDetoxRetreatAPI || {};\r\n    shared.entries = shared.entries || {};\r\n    shared.version = shared.version || 0;\r\n\r\n    if (typeof shared.key !== 'function') {\r\n      shared.key = function(url) {\r\n        return new URL(url, window.location.href).href;\r\n      };\r\n    }\r\n\r\n    if (typeof shared.load !== 'function') {\r\n      shared.load = function(url, force) {\r\n        var key = shared.key(url);\r\n        if (!force && shared.entries[key]) return shared.entries[key].promise;\r\n\r\n        var controller = typeof AbortController === 'function' ? new AbortController() : null;\r\n        var timedOut = false;\r\n        var timeoutId = window.setTimeout(function() {\r\n          timedOut = true;\r\n          if (controller) controller.abort();\r\n        }, 15000);\r\n\r\n        var entry = {};\r\n        entry.promise = fetch(key, {\r\n          method: 'GET',\r\n          credentials: 'same-origin',\r\n          headers: { Accept: 'application\/json' },\r\n          signal: controller ? controller.signal : undefined\r\n        }).then(function(response) {\r\n          if (!response.ok) throw new Error('API request failed with status ' + response.status);\r\n          return response.json();\r\n        }).then(function(payload) {\r\n          var items = Array.isArray(payload)\r\n            ? payload\r\n            : Array.isArray(payload.retreats)\r\n              ? payload.retreats\r\n              : Array.isArray(payload.data)\r\n                ? payload.data\r\n                : null;\r\n\r\n          if (!items) throw new Error('The API returned an unexpected response shape.');\r\n\r\n          var result = { key: key, items: items, version: ++shared.version };\r\n          entry.result = result;\r\n          window.dispatchEvent(new CustomEvent('vietnamdetox:retreats-loaded', { detail: result }));\r\n          return result;\r\n        }).catch(function(error) {\r\n          if (timedOut) error.vietnamDetoxTimedOut = true;\r\n          throw error;\r\n        }).finally(function() {\r\n          window.clearTimeout(timeoutId);\r\n        });\r\n\r\n        shared.entries[key] = entry;\r\n        return entry.promise;\r\n      };\r\n    }\r\n\r\n    return shared;\r\n  }\r\n\r\n  function cleanText(value) {\r\n    if (value === null || typeof value === 'undefined') return '';\r\n    var parser = new DOMParser();\r\n    var parsed = parser.parseFromString(String(value), 'text\/html');\r\n    return (parsed.body.textContent || '').replace(\/\\s+\/g, ' ').trim();\r\n  }\r\n\r\n  function safeUrl(value, allowImageData) {\r\n    if (!value) return '';\r\n    try {\r\n      var parsed = new URL(String(value), window.location.href);\r\n      var allowed = parsed.protocol === 'http:' || parsed.protocol === 'https:';\r\n      if (allowImageData && parsed.protocol === 'data:') allowed = \/^data:image\\\/\/i.test(String(value));\r\n      return allowed ? parsed.href : '';\r\n    } catch (error) {\r\n      return '';\r\n    }\r\n  }\r\n\r\n  function createElement(tag, className, text) {\r\n    var element = document.createElement(tag);\r\n    if (className) element.className = className;\r\n    if (typeof text === 'string') element.textContent = text;\r\n    return element;\r\n  }\r\n\r\n  var roots = document.querySelectorAll('[data-vroh-hero]');\r\n\r\n  roots.forEach(function(root) {\r\n    if (root.dataset.vrohReady === 'true') return;\r\n    root.dataset.vrohReady = 'true';\r\n\r\n    var panel = root.querySelector('[data-vroh-panel]');\r\n    var panelSurface = root.querySelector('[data-vroh-panel-surface]');\r\n    var panelBody = root.querySelector('[data-vroh-panel-body]');\r\n    var panelToggle = root.querySelector('[data-vroh-panel-toggle]');\r\n    var toggleLabel = root.querySelector('[data-vroh-toggle-label]');\r\n    var toggleIcon = root.querySelector('[data-vroh-toggle-icon]');\r\n    var background = root.querySelector('[data-vroh-background]');\r\n    var overlay = root.querySelector('[data-vroh-overlay]');\r\n    var locationCopy = root.querySelector('[data-vroh-location]');\r\n    var mediaStatus = root.querySelector('[data-vroh-media-status]');\r\n    var retreatLinks = root.querySelector('[data-vroh-retreat-links]');\r\n    var retreatStatus = root.querySelector('[data-vroh-retreat-status]');\r\n    var sliderUi = root.querySelector('[data-vroh-slider-ui]');\r\n    var dotsContainer = root.querySelector('[data-vroh-dots]');\r\n    var progress = root.querySelector('[data-vroh-progress]');\r\n    var apiUrl = root.getAttribute('data-api-url') || '\/wp-json\/retreats\/v1\/all?lang=en';\r\n    var sharedApi = getSharedRetreatApi();\r\n    var apiKey = sharedApi.key(apiUrl);\r\n    var mobileQuery = window.matchMedia('(max-width: 767px)');\r\n    var reducedMotionQuery = window.matchMedia('(prefers-reduced-motion: reduce)');\r\n    var duration = 8200;\r\n    var timerId = null;\r\n    var current = 0;\r\n    var slides = [];\r\n    var dots = [];\r\n    var links = [];\r\n    var lastVersion = 0;\r\n\r\n    function syncPanel() {\r\n      if (!panel || !panelSurface || !panelToggle || !toggleLabel || !toggleIcon) return;\r\n      var isCollapsed = panel.classList.contains('is-collapsed');\r\n      toggleLabel.textContent = isCollapsed ? 'Show info' : 'Hide box';\r\n      toggleIcon.textContent = isCollapsed ? '+' : '\\u00d7';\r\n      panelToggle.setAttribute('aria-label', isCollapsed ? 'Show introduction' : 'Hide introduction');\r\n      panelToggle.setAttribute('aria-expanded', String(!isCollapsed));\r\n      panelSurface.setAttribute('aria-hidden', String(isCollapsed));\r\n    }\r\n\r\n    function syncMediaLayout() {\r\n      if (!background || !overlay || !panelBody || !locationCopy) return;\r\n\r\n      if (mobileQuery.matches) {\r\n        if (background.parentElement !== panelBody) {\r\n          var mobileAnchor = locationCopy.parentElement === panelBody ? locationCopy : sliderUi;\r\n          panelBody.insertBefore(background, mobileAnchor);\r\n        }\r\n      } else if (background.parentElement !== root) {\r\n        root.insertBefore(background, overlay);\r\n      }\r\n    }\r\n\r\n    function preloadSlide(index) {\r\n      var slide = slides[index];\r\n      if (!slide || !slide.dataset.imageUrl) return;\r\n      var image = new Image();\r\n      image.src = slide.dataset.imageUrl;\r\n    }\r\n\r\n    function syncSlides() {\r\n      slides.forEach(function(slide, index) {\r\n        slide.classList.toggle('is-active', index === current);\r\n      });\r\n\r\n      dots.forEach(function(dot, index) {\r\n        var isActive = index === current;\r\n        dot.classList.toggle('is-active', isActive);\r\n        dot.setAttribute('aria-selected', String(isActive));\r\n        dot.tabIndex = isActive ? 0 : -1;\r\n      });\r\n\r\n      links.forEach(function(link, index) {\r\n        link.classList.toggle('is-active', index === current);\r\n      });\r\n    }\r\n\r\n    function restartProgress() {\r\n      if (!progress) return;\r\n      progress.classList.remove('is-animating');\r\n\r\n      if (reducedMotionQuery.matches || slides.length < 2) {\r\n        progress.style.transform = 'scaleX(1)';\r\n        return;\r\n      }\r\n\r\n      progress.style.transform = 'scaleX(0)';\r\n      void progress.offsetWidth;\r\n      progress.classList.add('is-animating');\r\n    }\r\n\r\n    function clearTimer() {\r\n      if (timerId === null) return;\r\n      window.clearTimeout(timerId);\r\n      timerId = null;\r\n    }\r\n\r\n    function queueNextSlide() {\r\n      clearTimer();\r\n      if (reducedMotionQuery.matches || document.hidden || slides.length < 2) return;\r\n      timerId = window.setTimeout(function() {\r\n        goToSlide(current + 1);\r\n      }, duration);\r\n    }\r\n\r\n    function goToSlide(index) {\r\n      if (!slides.length) return;\r\n      current = (index + slides.length) % slides.length;\r\n      syncSlides();\r\n      restartProgress();\r\n      preloadSlide((current + 1) % slides.length);\r\n      queueNextSlide();\r\n    }\r\n\r\n    function bindDynamicControls() {\r\n      dots.forEach(function(dot) {\r\n        dot.addEventListener('click', function() {\r\n          goToSlide(Number(dot.dataset.slideIndex));\r\n        });\r\n\r\n        dot.addEventListener('keydown', function(event) {\r\n          if (event.key !== 'ArrowRight' && event.key !== 'ArrowLeft') return;\r\n          event.preventDefault();\r\n          goToSlide(current + (event.key === 'ArrowRight' ? 1 : -1));\r\n          dots[current].focus();\r\n        });\r\n      });\r\n\r\n      links.forEach(function(link) {\r\n        link.addEventListener('mouseenter', function() {\r\n          goToSlide(Number(link.dataset.slideIndex));\r\n        });\r\n        link.addEventListener('focus', function() {\r\n          goToSlide(Number(link.dataset.slideIndex));\r\n        });\r\n      });\r\n    }\r\n\r\n    function renderRetreats(result) {\r\n      if (!result || result.key !== apiKey || result.version === lastVersion) return;\r\n      lastVersion = result.version;\r\n      clearTimer();\r\n      background.replaceChildren();\r\n      retreatLinks.replaceChildren();\r\n      dotsContainer.replaceChildren();\r\n\r\n      var items = result.items.filter(function(item) {\r\n        return item && typeof item === 'object';\r\n      });\r\n\r\n      if (!items.length) {\r\n        background.appendChild(createElement('div', 'vroh__media-status', 'No retreat images are currently available.'));\r\n        retreatLinks.appendChild(createElement('span', 'vroh__retreat-status', 'New retreats will be announced soon.'));\r\n        sliderUi.hidden = true;\r\n        slides = [];\r\n        dots = [];\r\n        links = [];\r\n        return;\r\n      }\r\n\r\n      items.forEach(function(item, index) {\r\n        var name = cleanText(item.name) || 'Vietnam Detox Retreat';\r\n        var location = cleanText(item.location) || 'Vietnam Detox';\r\n        var imageUrl = safeUrl(item.image, true);\r\n        var pageUrl = safeUrl(item.url, false);\r\n        var slide = createElement('div', 'vroh__slide');\r\n        slide.dataset.vrohSlide = '';\r\n        slide.dataset.imageUrl = imageUrl;\r\n        if (imageUrl) slide.style.backgroundImage = 'url(\"' + imageUrl.replace(\/\"\/g, '%22') + '\")';\r\n        else slide.classList.add('is-missing');\r\n        background.appendChild(slide);\r\n\r\n        var dot = createElement('button', 'vroh__slider-dot');\r\n        dot.type = 'button';\r\n        dot.setAttribute('role', 'tab');\r\n        dot.setAttribute('aria-label', 'Show image for ' + name);\r\n        dot.setAttribute('aria-selected', 'false');\r\n        dot.dataset.slideIndex = String(index);\r\n        dotsContainer.appendChild(dot);\r\n\r\n        var link = createElement(pageUrl ? 'a' : 'div', 'vroh__retreat-link');\r\n        if (pageUrl) link.href = pageUrl;\r\n        link.dataset.slideIndex = String(index);\r\n        link.appendChild(createElement('strong', '', name));\r\n        link.appendChild(createElement('span', '', location));\r\n        retreatLinks.appendChild(link);\r\n      });\r\n\r\n      slides = Array.prototype.slice.call(background.querySelectorAll('.vroh__slide'));\r\n      dots = Array.prototype.slice.call(dotsContainer.querySelectorAll('.vroh__slider-dot'));\r\n      links = Array.prototype.slice.call(retreatLinks.querySelectorAll('.vroh__retreat-link'));\r\n      current = 0;\r\n      sliderUi.hidden = slides.length < 2;\r\n      bindDynamicControls();\r\n      syncMediaLayout();\r\n      syncSlides();\r\n      restartProgress();\r\n      preloadSlide(slides.length > 1 ? 1 : 0);\r\n      queueNextSlide();\r\n    }\r\n\r\n    function showLoadError(error) {\r\n      if (lastVersion) return;\r\n      var message = error && error.vietnamDetoxTimedOut\r\n        ? 'Retreat images took too long to load.'\r\n        : 'Retreat images are temporarily unavailable.';\r\n\r\n      if (mediaStatus && mediaStatus.parentElement) mediaStatus.textContent = message;\r\n      if (retreatStatus && retreatStatus.parentElement) retreatStatus.textContent = 'Please use the retreat list below or refresh the page.';\r\n      sliderUi.hidden = true;\r\n    }\r\n\r\n    if (panelToggle) {\r\n      panelToggle.addEventListener('click', function() {\r\n        panel.classList.toggle('is-collapsed');\r\n        syncPanel();\r\n      });\r\n    }\r\n\r\n    window.addEventListener('vietnamdetox:retreats-loaded', function(event) {\r\n      renderRetreats(event.detail);\r\n    });\r\n\r\n    document.addEventListener('visibilitychange', function() {\r\n      if (document.hidden) clearTimer();\r\n      else {\r\n        restartProgress();\r\n        queueNextSlide();\r\n      }\r\n    });\r\n\r\n    function handleMotionPreference() {\r\n      restartProgress();\r\n      queueNextSlide();\r\n    }\r\n\r\n    if (typeof mobileQuery.addEventListener === 'function') {\r\n      mobileQuery.addEventListener('change', syncMediaLayout);\r\n      reducedMotionQuery.addEventListener('change', handleMotionPreference);\r\n    } else {\r\n      mobileQuery.addListener(syncMediaLayout);\r\n      reducedMotionQuery.addListener(handleMotionPreference);\r\n    }\r\n\r\n    syncPanel();\r\n    syncMediaLayout();\r\n\r\n    if (typeof window.fetch !== 'function') {\r\n      showLoadError(new Error('Fetch is unavailable.'));\r\n      return;\r\n    }\r\n\r\n    sharedApi.load(apiUrl, false).then(renderRetreats).catch(showLoadError);\r\n  });\r\n})();\r\n<\/script>\r\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-cb05801 e-flex e-con-boxed e-con e-parent\" data-id=\"cb05801\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-0a87492 elementor-widget elementor-widget-html\" data-id=\"0a87492\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!--\r\n  Elementor setup\r\n  1. Paste this entire file into ONE Elementor HTML widget.\r\n  2. Paste elementor-retreat-overview-intro.css into the same widget's\r\n     Advanced > Custom CSS field.\r\n\r\n  This component is static, so no JavaScript is required.\r\n-->\r\n\r\n<section class=\"vroi\" aria-label=\"Retreat overview introduction\">\r\n  <div class=\"vroi__inner\">\r\n    <p class=\"vroi__copy\">\r\n Kh\u00e1m ph\u00e1 c\u00e1c kh\u00f3a ngh\u1ec9 d\u01b0\u1ee1ng nh\u1ecbn \u0103n c\u00f3 h\u01b0\u1edbng d\u1eabn s\u1eafp t\u1edbi c\u1ee7a ch\u00fang t\u00f4i t\u1ea1i Vi\u1ec7t Nam, so s\u00e1nh c\u00e1c b\u1ed1i c\u1ea3nh kh\u00e1c nhau v\u00e0 ch\u1ecdn tr\u1ea3i nghi\u1ec7m m\u00e0 b\u1ea1n c\u1ea3m th\u1ea5y ph\u00f9 h\u1ee3p.\r\n    <\/p>\r\n  <\/div>\r\n<\/section>\r\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-2cc28ec e-flex e-con-boxed e-con e-parent\" data-id=\"2cc28ec\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-218e7d3 elementor-widget elementor-widget-html\" data-id=\"218e7d3\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!--\n  Elementor setup\n  1. Paste this entire file into ONE Elementor HTML widget.\n  2. Paste elementor-dynamic-retreat-list.css into the same widget's\n     Advanced > Custom CSS field.\n  3. The REST endpoint can be changed with the data-api-url attribute below.\n-->\n\n<section class=\"vdrl\" id=\"retreats\" data-vdrl=\"\" data-api-url=\"\/wp-json\/retreats\/v1\/all?lang=vi\" aria-label=\"Upcoming Vietnam Detox retreats\">\n  <div class=\"vdrl__wrap\">\n    <div class=\"vdrl__status\" data-vdrl-status=\"\" role=\"status\" aria-live=\"polite\">\n      <span class=\"vdrl__spinner\" aria-hidden=\"true\"><\/span>\n      <span data-vdrl-status-text=\"\">\u0110ang t\u1ea3i c\u00e1c kh\u00f3a ngh\u1ec9 d\u01b0\u1ee1ng s\u1eafp t\u1edbi...<\/span>\n    <\/div>\n\n    <div class=\"vdrl__grid\" data-vdrl-grid=\"\" aria-busy=\"true\" aria-label=\"Retreats\">\n      <article class=\"vdrl__skeleton\" aria-hidden=\"true\">\n        <div class=\"vdrl__skeleton-image\"><\/div>\n        <div class=\"vdrl__skeleton-body\"><i><\/i><i><\/i><i><\/i><i><\/i><\/div>\n      <\/article>\n      <article class=\"vdrl__skeleton\" aria-hidden=\"true\">\n        <div class=\"vdrl__skeleton-image\"><\/div>\n        <div class=\"vdrl__skeleton-body\"><i><\/i><i><\/i><i><\/i><i><\/i><\/div>\n      <\/article>\n      <article class=\"vdrl__skeleton\" aria-hidden=\"true\">\n        <div class=\"vdrl__skeleton-image\"><\/div>\n        <div class=\"vdrl__skeleton-body\"><i><\/i><i><\/i><i><\/i><i><\/i><\/div>\n      <\/article>\n    <\/div>\n\n    <noscript>\n      <p class=\"vdrl__noscript\">C\u1ea7n c\u00f3 JavaScript \u0111\u1ec3 t\u1ea3i l\u1ecbch tr\u00ecnh kh\u00f3a ngh\u1ec9 d\u01b0\u1ee1ng hi\u1ec7n t\u1ea1i.<\/p>\n    <\/noscript>\n  <\/div>\n<\/section>\n\n<script>\n(function() {\n  'use strict';\n\n  function getSharedRetreatApi() {\n    var shared = window.VietnamDetoxRetreatAPI = window.VietnamDetoxRetreatAPI || {};\n    shared.entries = shared.entries || {};\n    shared.version = shared.version || 0;\n\n    if (typeof shared.key !== 'function') {\n      shared.key = function(url) {\n        return new URL(url, window.location.href).href;\n      };\n    }\n\n    if (typeof shared.load !== 'function') {\n      shared.load = function(url, force) {\n        var key = shared.key(url);\n        if (!force && shared.entries[key]) return shared.entries[key].promise;\n\n        var controller = typeof AbortController === 'function' ? new AbortController() : null;\n        var timedOut = false;\n        var timeoutId = window.setTimeout(function() {\n          timedOut = true;\n          if (controller) controller.abort();\n        }, 15000);\n\n        var entry = {};\n        entry.promise = fetch(key, {\n          method: 'GET',\n          credentials: 'same-origin',\n          headers: { Accept: 'application\/json' },\n          signal: controller ? controller.signal : undefined\n        }).then(function(response) {\n          if (!response.ok) throw new Error('API request failed with status ' + response.status);\n          return response.json();\n        }).then(function(payload) {\n          var items = Array.isArray(payload)\n            ? payload\n            : Array.isArray(payload.retreats)\n              ? payload.retreats\n              : Array.isArray(payload.data)\n                ? payload.data\n                : null;\n\n          if (!items) throw new Error('The API returned an unexpected response shape.');\n\n          var result = { key: key, items: items, version: ++shared.version };\n          entry.result = result;\n          window.dispatchEvent(new CustomEvent('vietnamdetox:retreats-loaded', { detail: result }));\n          return result;\n        }).catch(function(error) {\n          if (timedOut) error.vietnamDetoxTimedOut = true;\n          throw error;\n        }).finally(function() {\n          window.clearTimeout(timeoutId);\n        });\n\n        shared.entries[key] = entry;\n        return entry.promise;\n      };\n    }\n\n    return shared;\n  }\n\n  var roots = document.querySelectorAll('[data-vdrl]');\n\n  var profiles = {\n    ANLYT: {\n      accent: '#C43010',\n      tagFallback: 'Y\u00ean T\u1eed',\n      chips: ['Quiet', 'Elevated', 'Deeply reflective'],\n      summary: 'A mountain retreat for guests seeking peace, structure and inner clarity.',\n      bestFor: 'Reflection, mindfulness and a more contemplative reset.',\n      buttonLabel: 'View An Retreat'\n    },\n    AWVH: {\n      accent: '#E06420',\n      tagFallback: 'Hu\u1ebf',\n      chips: ['Thermal', 'Restorative', 'Nature-led'],\n      summary: 'A restorative Hu\u1ebf retreat shaped by mineral springs, quiet nature and a softer pace of recovery.',\n      bestFor: 'Guests seeking deep rest, warm water therapies and a calmer nervous system.',\n      buttonLabel: 'View Y\u00ean Retreat'\n    },\n    PRIVATE: {\n      accent: '#1E3D20',\n      tagFallback: 'Private',\n      chips: ['Flexible', 'Discreet', 'Individual support'],\n      summary: 'A bespoke fasting retreat for guests who need privacy, flexibility and a more individual rhythm.',\n      bestFor: 'Couples, families, private groups and guests who prefer a premium private setting.',\n      buttonLabel: 'Explore Private Retreats',\n      byRequest: true\n    },\n    DEFAULT: {\n      accent: '#1E3D20',\n      tagFallback: 'Vietnam Detox',\n      chips: [],\n      summary: '',\n      bestFor: '',\n      buttonLabel: 'View Retreat'\n    }\n  };\n\n  function createElement(tag, className, text) {\n    var element = document.createElement(tag);\n    if (className) element.className = className;\n    if (typeof text === 'string') element.textContent = text;\n    return element;\n  }\n\n  function cleanText(value) {\n    if (value === null || typeof value === 'undefined') return '';\n    var parser = new DOMParser();\n    var documentValue = parser.parseFromString(String(value), 'text\/html');\n    return (documentValue.body.textContent || '').replace(\/\\s+\/g, ' ').trim();\n  }\n\n  function summarize(value, maximum) {\n    var text = cleanText(value);\n    if (!text || text.length <= maximum) return text;\n    var shortened = text.slice(0, maximum + 1).replace(\/\\s+\\S*$\/, '').trim();\n    return shortened + '\u2026';\n  }\n\n  function safeUrl(value, allowImageData) {\n    if (!value) return '';\n    try {\n      var parsed = new URL(String(value), window.location.href);\n      var allowed = parsed.protocol === 'http:' || parsed.protocol === 'https:';\n      if (allowImageData && parsed.protocol === 'data:') allowed = \/^data:image\\\/\/i.test(String(value));\n      return allowed ? parsed.href : '';\n    } catch (error) {\n      return '';\n    }\n  }\n\n  function retreatLandingPageUrl(value) {\n    var url = safeUrl(value, false);\n    if (!url) return '';\n\n    var parsed = new URL(url);\n    parsed.pathname = parsed.pathname.replace(\/\\\/retreats(?=\\\/|$)\/i, '') || '\/';\n    return parsed.href;\n  }\n\n  function parseApiDate(value) {\n    if (!value) return null;\n    var parts = String(value).match(\/^(\\d{1,2})\\\/(\\d{1,2})\\\/(\\d{4})$\/);\n    if (!parts) return null;\n    var date = new Date(Number(parts[3]), Number(parts[1]) - 1, Number(parts[2]), 12, 0, 0, 0);\n    return Number.isNaN(date.getTime()) ? null : date;\n  }\n\n  function formatDay(date) {\n    return new Intl.DateTimeFormat('en-GB', { day: 'numeric' }).format(date);\n  }\n\n  function formatMonthYear(date) {\n    return new Intl.DateTimeFormat('en-GB', { month: 'long', year: 'numeric' }).format(date);\n  }\n\n  function formatMonth(date) {\n    return new Intl.DateTimeFormat('en-GB', { month: 'long' }).format(date);\n  }\n\n  function formatDateRange(item) {\n    var start = item._start;\n    var end = item._end;\n    if (!start || !end) return cleanText(item.label) || 'Date to be confirmed';\n\n    var sameYear = start.getFullYear() === end.getFullYear();\n    var sameMonth = sameYear && start.getMonth() === end.getMonth();\n\n    if (sameMonth) {\n      return formatDay(start) + '\u2013' + formatDay(end) + ' ' + formatMonthYear(end);\n    }\n\n    if (sameYear) {\n      return formatDay(start) + ' ' + formatMonth(start) + '\u2013' + formatDay(end) + ' ' + formatMonthYear(end);\n    }\n\n    return formatDay(start) + ' ' + formatMonthYear(start) + '\u2013' + formatDay(end) + ' ' + formatMonthYear(end);\n  }\n\n  function availabilityText(item) {\n    return item && item.limited === true ? 'Limited places' : 'Open';\n  }\n\n  function profileFor(item) {\n    var sku = cleanText(item && item.retreat_sku).toUpperCase();\n    var name = cleanText(item && item.name);\n    if (profiles[sku]) return profiles[sku];\n    if (\/private|corporate\/i.test(name)) return profiles.PRIVATE;\n    return profiles.DEFAULT;\n  }\n\n  function upcomingDates(item, byRequest) {\n    if (byRequest || !Array.isArray(item.dates)) return [];\n\n    var today = new Date();\n    today.setHours(0, 0, 0, 0);\n\n    return item.dates.map(function(date) {\n      var normalized = Object.assign({}, date);\n      normalized._start = parseApiDate(date.start);\n      normalized._end = parseApiDate(date.end) || normalized._start;\n      return normalized;\n    }).filter(function(date) {\n      return !date._end || date._end >= today;\n    }).sort(function(a, b) {\n      if (!a._start && !b._start) return 0;\n      if (!a._start) return 1;\n      if (!b._start) return -1;\n      return a._start - b._start;\n    });\n  }\n\n  function priceDetails(item, byRequest) {\n    if (byRequest) return { main: 'Custom dates and setting', suffix: '' };\n    if (!Array.isArray(item.packages) || !item.packages.length) {\n      return { main: 'Pricing on retreat page', suffix: '' };\n    }\n\n    var perPersonPrices = item.packages.map(function(packageItem) {\n      var price = Number(packageItem.price);\n      var people = Math.max(1, Number(packageItem.person) || 1);\n      return Number.isFinite(price) && price > 0 ? price \/ people : null;\n    }).filter(function(price) {\n      return price !== null;\n    });\n\n    if (!perPersonPrices.length) return { main: 'Pricing on retreat page', suffix: '' };\n\n    var lowest = Math.round(Math.min.apply(Math, perPersonPrices));\n    return {\n      main: 'From VND ' + new Intl.NumberFormat('en-US', { maximumFractionDigits: 0 }).format(lowest),\n      suffix: 'per person'\n    };\n  }\n\n  function appendLabelValue(parent, labelText, valueText) {\n    var line = createElement('div', 'vdrl__date-line');\n    line.appendChild(createElement('span', 'vdrl__meta-label', labelText));\n    line.appendChild(createElement('span', 'vdrl__date-value', valueText));\n    parent.appendChild(line);\n  }\n\n  function createCard(item, instanceId, cardIndex) {\n    var profile = profileFor(item);\n    var byRequest = profile.byRequest === true;\n    var dates = upcomingDates(item, byRequest);\n    var name = cleanText(item.name) || 'Vietnam Detox Retreat';\n    var location = cleanText(item.location) || profile.tagFallback;\n    var linkUrl = retreatLandingPageUrl(item.url);\n    var imageUrl = safeUrl(item.image, true);\n    var summary = profile.summary || summarize(item.description, 210) || 'A guided Vietnam Detox fasting retreat.';\n    var price = priceDetails(item, byRequest);\n    var card = createElement('article', 'vdrl__card');\n    var media = createElement('div', 'vdrl__media');\n\n    card.style.setProperty('--vdrl-card-accent', profile.accent);\n\n    if (imageUrl) {\n      var image = createElement('img', 'vdrl__image');\n      image.src = imageUrl;\n      image.alt = name;\n      image.loading = 'lazy';\n      image.decoding = 'async';\n      image.addEventListener('error', function() {\n        media.classList.add('is-missing');\n        image.remove();\n      }, { once: true });\n      media.appendChild(image);\n    } else {\n      media.classList.add('is-missing');\n    }\n\n    var badgeText = byRequest\n      ? 'By Request'\n      : dates.length > 1\n        ? 'Multiple dates available'\n        : dates.length === 1\n          ? 'Next date available'\n          : 'Dates to be announced';\n\n    media.appendChild(createElement('div', 'vdrl__badge', badgeText));\n    card.appendChild(media);\n    card.appendChild(createElement('div', 'vdrl__accent'));\n\n    var body = createElement('div', 'vdrl__body');\n    var top = createElement('div', 'vdrl__top');\n    top.appendChild(createElement('span', 'vdrl__tag', location));\n\n    var heading = createElement('h3', 'vdrl__title');\n    if (linkUrl) {\n      var headingLink = createElement('a', '', name);\n      headingLink.href = linkUrl;\n      heading.appendChild(headingLink);\n    } else {\n      heading.textContent = name;\n    }\n    top.appendChild(heading);\n\n    if (profile.chips.length) {\n      var chipRow = createElement('div', 'vdrl__chips');\n      profile.chips.forEach(function(chipText) {\n        chipRow.appendChild(createElement('span', 'vdrl__chip', chipText));\n      });\n      top.appendChild(chipRow);\n    }\n    body.appendChild(top);\n\n    var summaryBlock = createElement('div', 'vdrl__summary');\n    summaryBlock.appendChild(createElement('p', '', summary));\n    body.appendChild(summaryBlock);\n\n    if (profile.bestFor) {\n      var meta = createElement('div', 'vdrl__meta');\n      meta.appendChild(createElement('span', 'vdrl__meta-label', 'Best for'));\n      meta.appendChild(createElement('p', 'vdrl__meta-value', profile.bestFor));\n      body.appendChild(meta);\n    }\n\n    var dateBlock = createElement('div', 'vdrl__dates');\n    if (byRequest) {\n      appendLabelValue(dateBlock, 'Availability', 'Available by request.');\n    } else if (dates.length) {\n      appendLabelValue(dateBlock, 'Next date', formatDateRange(dates[0]) + ' \u00b7 ' + availabilityText(dates[0]));\n\n      var earlyBirdNote = cleanText(item.earlyBirdNote);\n      if (earlyBirdNote) dateBlock.appendChild(createElement('p', 'vdrl__early-bird', earlyBirdNote));\n\n      if (dates.length > 1) {\n        var itemId = String(item.id || cardIndex).replace(\/[^a-zA-Z0-9_-]\/g, '');\n        var datePanelId = 'vdrl-dates-' + instanceId + '-' + itemId;\n        var extras = createElement('div', 'vdrl__extra-dates is-collapsed');\n        extras.id = datePanelId;\n        extras.setAttribute('aria-hidden', 'true');\n        var list = createElement('ul');\n\n        dates.slice(1).forEach(function(date) {\n          list.appendChild(createElement('li', '', formatDateRange(date) + ' \u00b7 ' + availabilityText(date)));\n        });\n\n        extras.appendChild(list);\n        dateBlock.appendChild(extras);\n\n        var toggleLabel = dates.length === 2 ? 'View other date' : 'View other dates';\n        var toggle = createElement('button', 'vdrl__dates-toggle', toggleLabel);\n        toggle.type = 'button';\n        toggle.setAttribute('aria-controls', datePanelId);\n        toggle.setAttribute('aria-expanded', 'false');\n        toggle.addEventListener('click', function() {\n          var isCollapsed = extras.classList.toggle('is-collapsed');\n          extras.setAttribute('aria-hidden', String(isCollapsed));\n          toggle.setAttribute('aria-expanded', String(!isCollapsed));\n          toggle.firstChild.nodeValue = isCollapsed ? toggleLabel : 'Hide other dates';\n        });\n        dateBlock.appendChild(toggle);\n      }\n    } else {\n      appendLabelValue(dateBlock, 'Availability', 'New dates will be announced soon.');\n    }\n    body.appendChild(dateBlock);\n\n    var footer = createElement('div', 'vdrl__footer');\n    var priceElement = createElement('div', 'vdrl__price', price.main);\n    if (price.suffix) priceElement.appendChild(createElement('span', '', ' ' + price.suffix));\n    footer.appendChild(priceElement);\n\n    if (linkUrl) {\n      var button = createElement('a', 'vdrl__button', profile.buttonLabel);\n      button.href = linkUrl;\n      footer.appendChild(button);\n    }\n\n    body.appendChild(footer);\n    card.appendChild(body);\n    return card;\n  }\n\n  roots.forEach(function(root) {\n    if (root.dataset.vdrlReady === 'true') return;\n    root.dataset.vdrlReady = 'true';\n\n    window.__vdrlInstanceCounter = (window.__vdrlInstanceCounter || 0) + 1;\n    var instanceId = window.__vdrlInstanceCounter;\n    var grid = root.querySelector('[data-vdrl-grid]');\n    var status = root.querySelector('[data-vdrl-status]');\n    var apiUrl = root.getAttribute('data-api-url') || '\/wp-json\/retreats\/v1\/all?lang=en';\n    var sharedApi = getSharedRetreatApi();\n    var apiKey = sharedApi.key(apiUrl);\n    var lastVersion = 0;\n\n    function showLoading() {\n      status.hidden = false;\n      status.className = 'vdrl__status';\n      status.setAttribute('role', 'status');\n      status.replaceChildren();\n      status.appendChild(createElement('span', 'vdrl__spinner'));\n      status.appendChild(createElement('span', '', 'Loading upcoming retreats\u2026'));\n      grid.hidden = false;\n      grid.setAttribute('aria-busy', 'true');\n      grid.innerHTML = '<article class=\"vdrl__skeleton\" aria-hidden=\"true\"><div class=\"vdrl__skeleton-image\"><\/div><div class=\"vdrl__skeleton-body\"><i><\/i><i><\/i><i><\/i><i><\/i><\/div><\/article><article class=\"vdrl__skeleton\" aria-hidden=\"true\"><div class=\"vdrl__skeleton-image\"><\/div><div class=\"vdrl__skeleton-body\"><i><\/i><i><\/i><i><\/i><i><\/i><\/div><\/article><article class=\"vdrl__skeleton\" aria-hidden=\"true\"><div class=\"vdrl__skeleton-image\"><\/div><div class=\"vdrl__skeleton-body\"><i><\/i><i><\/i><i><\/i><i><\/i><\/div><\/article>';\n    }\n\n    function showMessage(message, type, allowRetry) {\n      grid.replaceChildren();\n      grid.hidden = true;\n      grid.removeAttribute('aria-busy');\n      status.hidden = false;\n      status.className = 'vdrl__status vdrl__status--' + type;\n      status.setAttribute('role', type === 'error' ? 'alert' : 'status');\n      status.replaceChildren(createElement('p', '', message));\n\n      if (allowRetry) {\n        var retry = createElement('button', 'vdrl__retry', 'Try again');\n        retry.type = 'button';\n        retry.addEventListener('click', function() {\n          loadRetreats(true);\n        });\n        status.appendChild(retry);\n      }\n    }\n\n    function renderResult(result) {\n      if (!result || result.key !== apiKey || result.version === lastVersion) return;\n      lastVersion = result.version;\n      var items = result.items;\n\n      if (!items.length) {\n        showMessage('No retreats are currently available. Please check back soon.', 'empty', false);\n        return;\n      }\n\n      var fragment = document.createDocumentFragment();\n      items.forEach(function(item, index) {\n        fragment.appendChild(createCard(item || {}, instanceId, index));\n      });\n\n      grid.replaceChildren(fragment);\n      grid.hidden = false;\n      grid.removeAttribute('aria-busy');\n      status.hidden = true;\n    }\n\n    function showLoadError(error) {\n      if (lastVersion) return;\n      if (error && error.vietnamDetoxTimedOut) {\n        showMessage('The retreat schedule took too long to load. Please try again.', 'error', true);\n        return;\n      }\n      showMessage('We could not load the current retreat schedule. Please try again.', 'error', true);\n    }\n\n    function loadRetreats(force) {\n      showLoading();\n\n      if (typeof window.fetch !== 'function') {\n        showMessage('This browser cannot load the current retreat schedule.', 'error', false);\n        return;\n      }\n\n      sharedApi.load(apiUrl, force === true).then(renderResult).catch(showLoadError);\n    }\n\n    window.addEventListener('vietnamdetox:retreats-loaded', function(event) {\n      renderResult(event.detail);\n    });\n\n    loadRetreats(false);\n  });\n})();\n<\/script>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-ebf20ab e-con-full vbook__booking-card e-flex e-con e-parent\" data-id=\"ebf20ab\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-f127263 elementor-widget elementor-widget-html\" data-id=\"f127263\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!--\r\n  Elementor setup\r\n  1. Paste this file into an HTML widget inside the outer CTA container.\r\n  2. Add a separate Bookly Booking form or Elementor Shortcode widget in the\r\n     vrdc__booking-card inner container below this HTML widget.\r\n  3. Paste elementor-retreat-decision-cta.css into the OUTER container's\r\n     Advanced > Custom CSS field.\r\n\r\n  The HTML widget cannot run WordPress shortcodes. Use [bookly-form] only in\r\n  Elementor's Shortcode widget, not in this HTML widget.\r\n-->\r\n\r\n<section class=\"vrdc\" aria-labelledby=\"vrdc-title\">\r\n  <div class=\"vrdc__inner\">\r\n    <h2 class=\"vrdc__title\" id=\"vrdc-title\">B\u1ea1n kh\u00f4ng ch\u1eafc kh\u00f3a ngh\u1ec9 d\u01b0\u1ee1ng n\u00e0o ph\u00f9 h\u1ee3p v\u1edbi m\u00ecnh?<\/h2>\r\n\r\n    <p class=\"vrdc__copy\">\r\n H\u00e3y kh\u00e1m ph\u00e1 c\u00e1c trang th\u00f4ng tin v\u1ec1 t\u1eebng ch\u01b0\u01a1ng tr\u00ecnh t\u0129nh t\u00e2m ho\u1eb7c \u0111\u1eb7t l\u1ecbch tr\u00f2 chuy\u1ec7n mi\u1ec5n ph\u00ed v\u1edbi Dieter tr\u01b0\u1edbc khi \u0111\u01b0a ra quy\u1ebft \u0111\u1ecbnh.\r\n    <\/p>\r\n\r\n    <div class=\"vrdc__buttons\">\r\n      <a href=\"\/redesign-clickdummy-2026\/faq.html\" class=\"vrdc__button vrdc__button--outline\">FAQ<\/a>\r\n    <\/div>\r\n  <\/div>\r\n<\/section>\r\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-77b5163 e-con-full vrdc__booking-card e-flex e-con e-child\" data-id=\"77b5163\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-e96bf09 elementor-widget elementor-widget-shortcode\" data-id=\"e96bf09\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"shortcode.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\"><!--\nPlugin Name: Bookly - Responsive WordPress Appointment Booking and Scheduling Plugin\nPlugin URI: https:\/\/www.booking-wp-plugin.com\/?utm_source=bookly_admin&utm_medium=plugins_page&utm_campaign=plugins_page\nVersion: 27.9-->\n<style type=\"text\/css\">\n    :root {\n        --bookly-main-color: #f4662f !important;\n        --bookly-color: #f4662f !important;\n    }\n\n    <\/style><div class=\"bookly-css-root\">\n    <div id=\"bookly-form-container-6a9917f376b8d\" class=\"bookly-form\" data-form_id=\"\" aria-live=\"polite\">\n        <div style=\"text-align: center\"><img decoding=\"async\" src=\"https:\/\/staging.vietnamdetox.com\/wp-includes\/js\/tinymce\/skins\/lightgray\/img\/loader.gif\" alt=\"Loading...\"\/><\/div>\n    <\/div>\n<\/div>\n    <div class=\"powered-by-bookly\">Powered by        <a href=\"https:\/\/www.booking-wp-plugin.com\/?utm_source=referral&utm_medium=booking_widget\" target=\"_blank\">Bookly<\/a> \u2014\n        <a href=\"https:\/\/www.booking-wp-plugin.com\/?utm_source=referral&utm_medium=booking_widget\" target=\"_blank\">WordPress Booking Plugin<\/a>\n    <\/div>\n<script type=\"text\/javascript\">\n    (function (win, fn) {\n        var done = false, top = true,\n            doc = win.document,\n            root = doc.documentElement,\n            modern = doc.addEventListener,\n            add = modern ? 'addEventListener' : 'attachEvent',\n            rem = modern ? 'removeEventListener' : 'detachEvent',\n            pre = modern ? '' : 'on',\n            init = function (e) {\n                if (e.type == 'readystatechange') if (doc.readyState != 'complete') return;\n                (e.type == 'load' ? win : doc)[rem](pre + e.type, init, false);\n                if (!done) {\n                    done = true;\n                    fn.call(win, e.type || e);\n                }\n            },\n            poll = function () {\n                try {\n                    root.doScroll('left');\n                } catch (e) {\n                    setTimeout(poll, 50);\n                    return;\n                }\n                init('poll');\n            };\n        if (doc.readyState == 'complete') fn.call(win, 'lazy');\n        else {\n            if (!modern) if (root.doScroll) {\n                try {\n                    top = !win.frameElement;\n                } catch (e) {\n                }\n                if (top) poll();\n            }\n            doc[add](pre + 'DOMContentLoaded', init, false);\n            doc[add](pre + 'readystatechange', init, false);\n            win[add](pre + 'load', init, false);\n        }\n    })(window, function () {\n        window.bookly( {\"form_id\":\"6a9917f376b8d\",\"form_data\":{\"skip_service_step\":1,\"hide_service_part1\":1,\"hide_service_part2\":1,\"defaults\":{\"service_id\":2,\"staff_id\":2,\"location_id\":0,\"category_id\":0,\"units\":0,\"date_from\":0,\"time_from\":0,\"time_to\":0}},\"status\":{\"booking\":\"new\"},\"form_token\":null,\"skip_steps\":{\"service_part1\":1,\"service_part2\":1,\"extras\":1,\"time\":0,\"repeat\":1,\"cart\":1},\"errors\":{\"session_error\":\"Session error.\",\"form_id_error\":\"Form ID error.\",\"cart_item_not_available\":\"The selected time is not available anymore. Please, choose another time slot.\",\"pay_locally_not_available\":\"Pay locally is not available.\",\"invalid_gateway\":\"Invalid gateway.\",\"payment_error\":\"Error.\",\"incorrect_username_password\":\"T\\u00ean ng\\u01b0\\u1eddi d\\u00f9ng ho\\u1eb7c m\\u1eadt kh\\u1ea9u kh\\u00f4ng \\u0111\\u00fang.\"},\"form_attributes\":{\"hide_categories\":true,\"hide_services\":true,\"hide_staff_members\":true,\"show_number_of_persons\":false,\"hide_service_duration\":true,\"hide_locations\":true,\"hide_quantity\":true,\"hide_date\":true,\"hide_week_days\":true,\"hide_time_range\":true},\"use_client_time_zone\":0,\"defaults\":{\"service_id\":2,\"staff_id\":2,\"location_id\":0,\"category_id\":0},\"datepicker_mode\":\"text-accent\",\"facebook\":{\"enabled\":0,\"appId\":\"\"}} );\n    });\n<\/script><\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>\u0110ang t\u1ea3i h\u00ecnh \u1ea3nh kh\u00f3a ngh\u1ec9 d\u01b0\u1ee1ng&#8230; \u1ea8n h\u1ed9p tho\u1ea1i \u00d7 Vietnam Detox \u00b7 C\u00e1c kh\u00f3a ngh\u1ec9 d\u01b0\u1ee1ng nh\u1ecbn \u0103n c\u00f3 h\u01b0\u1edbng d\u1eabn t\u1ea1i Vi\u1ec7t Nam C\u00e1c kh\u00f3a ngh\u1ec9 d\u01b0\u1ee1ng d\u00e0nh cho nh\u1eefng ng\u01b0\u1eddi \u0111ang g\u00e1nh v\u00e1c qu\u00e1 nhi\u1ec1u. Nh\u1ecbn \u0103n theo ph\u01b0\u01a1ng ph\u00e1p Buchinger c\u00f3 h\u01b0\u1edbng d\u1eabn t\u1ea1i Vi\u1ec7t Nam \u2014 h\u00e3y so s\u00e1nh [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"footnotes":""},"class_list":["post-19086","page","type-page","status-publish","hentry"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Retreats - Staging Vietnamdetox<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/staging.vietnamdetox.com\/vi\/tong-quan-ve-khoa-nghi-duong\/\" \/>\n<meta property=\"og:locale\" content=\"vi_VN\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Retreats - Staging Vietnamdetox\" \/>\n<meta property=\"og:description\" content=\"\u0110ang t\u1ea3i h\u00ecnh \u1ea3nh kh\u00f3a ngh\u1ec9 d\u01b0\u1ee1ng&#8230; \u1ea8n h\u1ed9p tho\u1ea1i \u00d7 Vietnam Detox \u00b7 C\u00e1c kh\u00f3a ngh\u1ec9 d\u01b0\u1ee1ng nh\u1ecbn \u0103n c\u00f3 h\u01b0\u1edbng d\u1eabn t\u1ea1i Vi\u1ec7t Nam C\u00e1c kh\u00f3a ngh\u1ec9 d\u01b0\u1ee1ng d\u00e0nh cho nh\u1eefng ng\u01b0\u1eddi \u0111ang g\u00e1nh v\u00e1c qu\u00e1 nhi\u1ec1u. Nh\u1ecbn \u0103n theo ph\u01b0\u01a1ng ph\u00e1p Buchinger c\u00f3 h\u01b0\u1edbng d\u1eabn t\u1ea1i Vi\u1ec7t Nam \u2014 h\u00e3y so s\u00e1nh [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/staging.vietnamdetox.com\/vi\/tong-quan-ve-khoa-nghi-duong\/\" \/>\n<meta property=\"og:site_name\" content=\"Staging Vietnamdetox\" \/>\n<meta property=\"article:modified_time\" content=\"2026-08-22T06:54:06+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u01af\u1edbc t\u00ednh th\u1eddi gian \u0111\u1ecdc\" \/>\n\t<meta name=\"twitter:data1\" content=\"2 ph\u00fat\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/staging.vietnamdetox.com\\\/vi\\\/tong-quan-ve-khoa-nghi-duong\\\/\",\"url\":\"https:\\\/\\\/staging.vietnamdetox.com\\\/vi\\\/tong-quan-ve-khoa-nghi-duong\\\/\",\"name\":\"Retreats - Staging Vietnamdetox\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/staging.vietnamdetox.com\\\/vi\\\/#website\"},\"datePublished\":\"2026-08-12T06:04:29+00:00\",\"dateModified\":\"2026-08-22T06:54:06+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/staging.vietnamdetox.com\\\/vi\\\/tong-quan-ve-khoa-nghi-duong\\\/#breadcrumb\"},\"inLanguage\":\"vi\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/staging.vietnamdetox.com\\\/vi\\\/tong-quan-ve-khoa-nghi-duong\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/staging.vietnamdetox.com\\\/vi\\\/tong-quan-ve-khoa-nghi-duong\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/staging.vietnamdetox.com\\\/vi\\\/trang-chu-2\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Retreats\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/staging.vietnamdetox.com\\\/vi\\\/#website\",\"url\":\"https:\\\/\\\/staging.vietnamdetox.com\\\/vi\\\/\",\"name\":\"Staging Vietnamdetox\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/staging.vietnamdetox.com\\\/vi\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/staging.vietnamdetox.com\\\/vi\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"vi\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/staging.vietnamdetox.com\\\/vi\\\/#organization\",\"name\":\"Staging Vietnamdetox\",\"url\":\"https:\\\/\\\/staging.vietnamdetox.com\\\/vi\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"vi\",\"@id\":\"https:\\\/\\\/staging.vietnamdetox.com\\\/vi\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/staging.vietnamdetox.com\\\/wp-content\\\/uploads\\\/2026\\\/05\\\/logo-icon-color_cutout.svg\",\"contentUrl\":\"https:\\\/\\\/staging.vietnamdetox.com\\\/wp-content\\\/uploads\\\/2026\\\/05\\\/logo-icon-color_cutout.svg\",\"width\":314,\"height\":435,\"caption\":\"Staging Vietnamdetox\"},\"image\":{\"@id\":\"https:\\\/\\\/staging.vietnamdetox.com\\\/vi\\\/#\\\/schema\\\/logo\\\/image\\\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Retreats - Staging Vietnamdetox","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/staging.vietnamdetox.com\/vi\/tong-quan-ve-khoa-nghi-duong\/","og_locale":"vi_VN","og_type":"article","og_title":"Retreats - Staging Vietnamdetox","og_description":"\u0110ang t\u1ea3i h\u00ecnh \u1ea3nh kh\u00f3a ngh\u1ec9 d\u01b0\u1ee1ng&#8230; \u1ea8n h\u1ed9p tho\u1ea1i \u00d7 Vietnam Detox \u00b7 C\u00e1c kh\u00f3a ngh\u1ec9 d\u01b0\u1ee1ng nh\u1ecbn \u0103n c\u00f3 h\u01b0\u1edbng d\u1eabn t\u1ea1i Vi\u1ec7t Nam C\u00e1c kh\u00f3a ngh\u1ec9 d\u01b0\u1ee1ng d\u00e0nh cho nh\u1eefng ng\u01b0\u1eddi \u0111ang g\u00e1nh v\u00e1c qu\u00e1 nhi\u1ec1u. Nh\u1ecbn \u0103n theo ph\u01b0\u01a1ng ph\u00e1p Buchinger c\u00f3 h\u01b0\u1edbng d\u1eabn t\u1ea1i Vi\u1ec7t Nam \u2014 h\u00e3y so s\u00e1nh [&hellip;]","og_url":"https:\/\/staging.vietnamdetox.com\/vi\/tong-quan-ve-khoa-nghi-duong\/","og_site_name":"Staging Vietnamdetox","article_modified_time":"2026-08-22T06:54:06+00:00","twitter_card":"summary_large_image","twitter_misc":{"\u01af\u1edbc t\u00ednh th\u1eddi gian \u0111\u1ecdc":"2 ph\u00fat"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/staging.vietnamdetox.com\/vi\/tong-quan-ve-khoa-nghi-duong\/","url":"https:\/\/staging.vietnamdetox.com\/vi\/tong-quan-ve-khoa-nghi-duong\/","name":"Retreats - Staging Vietnamdetox","isPartOf":{"@id":"https:\/\/staging.vietnamdetox.com\/vi\/#website"},"datePublished":"2026-08-12T06:04:29+00:00","dateModified":"2026-08-22T06:54:06+00:00","breadcrumb":{"@id":"https:\/\/staging.vietnamdetox.com\/vi\/tong-quan-ve-khoa-nghi-duong\/#breadcrumb"},"inLanguage":"vi","potentialAction":[{"@type":"ReadAction","target":["https:\/\/staging.vietnamdetox.com\/vi\/tong-quan-ve-khoa-nghi-duong\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/staging.vietnamdetox.com\/vi\/tong-quan-ve-khoa-nghi-duong\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/staging.vietnamdetox.com\/vi\/trang-chu-2\/"},{"@type":"ListItem","position":2,"name":"Retreats"}]},{"@type":"WebSite","@id":"https:\/\/staging.vietnamdetox.com\/vi\/#website","url":"https:\/\/staging.vietnamdetox.com\/vi\/","name":"Staging Vietnamdetox","description":"","publisher":{"@id":"https:\/\/staging.vietnamdetox.com\/vi\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/staging.vietnamdetox.com\/vi\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"vi"},{"@type":"Organization","@id":"https:\/\/staging.vietnamdetox.com\/vi\/#organization","name":"Staging Vietnamdetox","url":"https:\/\/staging.vietnamdetox.com\/vi\/","logo":{"@type":"ImageObject","inLanguage":"vi","@id":"https:\/\/staging.vietnamdetox.com\/vi\/#\/schema\/logo\/image\/","url":"https:\/\/staging.vietnamdetox.com\/wp-content\/uploads\/2026\/05\/logo-icon-color_cutout.svg","contentUrl":"https:\/\/staging.vietnamdetox.com\/wp-content\/uploads\/2026\/05\/logo-icon-color_cutout.svg","width":314,"height":435,"caption":"Staging Vietnamdetox"},"image":{"@id":"https:\/\/staging.vietnamdetox.com\/vi\/#\/schema\/logo\/image\/"}}]}},"_hostinger_reach_plugin_has_subscription_block":false,"_hostinger_reach_plugin_is_elementor":false,"_links":{"self":[{"href":"https:\/\/staging.vietnamdetox.com\/vi\/wp-json\/wp\/v2\/pages\/19086","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/staging.vietnamdetox.com\/vi\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/staging.vietnamdetox.com\/vi\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/staging.vietnamdetox.com\/vi\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/staging.vietnamdetox.com\/vi\/wp-json\/wp\/v2\/comments?post=19086"}],"version-history":[{"count":4,"href":"https:\/\/staging.vietnamdetox.com\/vi\/wp-json\/wp\/v2\/pages\/19086\/revisions"}],"predecessor-version":[{"id":19352,"href":"https:\/\/staging.vietnamdetox.com\/vi\/wp-json\/wp\/v2\/pages\/19086\/revisions\/19352"}],"wp:attachment":[{"href":"https:\/\/staging.vietnamdetox.com\/vi\/wp-json\/wp\/v2\/media?parent=19086"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}