{"id":14164,"date":"2026-07-09T11:38:11","date_gmt":"2026-07-09T17:38:11","guid":{"rendered":"https:\/\/sunnyside.com.mx\/?page_id=14164"},"modified":"2026-10-09T11:07:52","modified_gmt":"2026-10-09T17:07:52","slug":"ods-rm","status":"publish","type":"page","link":"https:\/\/sunnyside.com.mx\/es\/ods-rm\/","title":{"rendered":"ODS RM"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"14164\" class=\"elementor elementor-14164\" data-elementor-post-type=\"page\">\n\t\t\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-bd70579 elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"bd70579\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-199758d\" data-id=\"199758d\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-59f6d35 elementor-widget elementor-widget-spacer\" data-id=\"59f6d35\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"spacer.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-spacer\">\n\t\t\t<div class=\"elementor-spacer-inner\"><\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-3506fda elementor-widget elementor-widget-html\" data-id=\"3506fda\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<!-- =========================================================\n     SUNNYSIDE DMC SERVICES\n     ODS RIVIERA MAYA\n     OPTION 1 \u2014 OPERATIONS APP\n========================================================= -->\n\n<section\n  id=\"ss-rm-app-header\"\n  aria-labelledby=\"ss-rm-app-title\"\n>\n\n  <!-- BACK -->\n  <a\n    class=\"ss-rm-app-back\"\n    href=\"https:\/\/sunnyside.com.mx\/central-de-reservas\/\"\n    aria-label=\"Volver a Central de Reservas\"\n  >\n\n    <span class=\"ss-rm-app-back-icon\">\n\n      <svg viewBox=\"0 0 24 24\">\n        <path d=\"M15 18l-6-6 6-6\"><\/path>\n      <\/svg>\n\n    <\/span>\n\n    <span class=\"ss-rm-app-back-copy\">\n      <small>Volver a<\/small>\n      <strong>Central de Reservas<\/strong>\n    <\/span>\n\n  <\/a>\n\n\n  <!-- TITLE -->\n  <div class=\"ss-rm-app-title\">\n\n    <span class=\"ss-rm-app-eyebrow\">\n      Service Orders\n    <\/span>\n\n    <h1 id=\"ss-rm-app-title\">\n      ODS Riviera Maya\n    <\/h1>\n\n    <p>\n      Generaci\u00f3n y administraci\u00f3n de \u00f3rdenes de servicio.\n    <\/p>\n\n  <\/div>\n\n\n  <!-- DESTINATION -->\n  <div class=\"ss-rm-app-destination\">\n\n    <span class=\"ss-rm-app-location-icon\">\n\n      <svg viewBox=\"0 0 24 24\">\n        <path d=\"M12 21s6-5.1 6-11a6 6 0 1 0-12 0c0 5.9 6 11 6 11Z\"><\/path>\n        <circle cx=\"12\" cy=\"10\" r=\"2.2\"><\/circle>\n      <\/svg>\n\n    <\/span>\n\n    <span class=\"ss-rm-app-location-copy\">\n\n      <small>\n        Destination\n      <\/small>\n\n      <strong>\n        CUN \/ RM\n      <\/strong>\n\n    <\/span>\n\n  <\/div>\n\n<\/section>\n\n\n<style>\n\n\/* =========================================================\n   ISOLATION\n========================================================= *\/\n\n#ss-rm-app-header,\n#ss-rm-app-header * {\n  box-sizing: border-box;\n}\n\n\n\/* =========================================================\n   HEADER\n========================================================= *\/\n\n#ss-rm-app-header {\n\n  --navy: #071d34;\n  --navy-2: #0c2b49;\n\n  --gold: #c39a57;\n  --gold-dark: #a67b3e;\n\n  --white: #ffffff;\n  --soft: #f6f8fa;\n\n  --text: #18212f;\n  --muted: #707d8b;\n  --border: #e0e6ec;\n\n  width:\n    min(\n      calc(100% - 32px),\n      1500px\n    );\n\n  min-height: 108px;\n\n  margin:\n    20px auto\n    10px;\n\n  padding:\n    18px 20px;\n\n  display: grid;\n\n  grid-template-columns:\n    220px\n    minmax(0,1fr)\n    auto;\n\n  align-items: center;\n\n  gap: 22px;\n\n  position: relative;\n\n  overflow: hidden;\n\n  background:\n    #ffffff;\n\n  border:\n    1px solid\n    var(--border);\n\n  border-radius:\n    16px;\n\n  box-shadow:\n    0 8px 26px\n    rgba(7,29,52,.055);\n\n  font-family:\n    Arial,\n    Helvetica,\n    sans-serif;\n\n}\n\n\n\/* GOLD TOP LINE *\/\n\n#ss-rm-app-header::before {\n\n  content: \"\";\n\n  position: absolute;\n\n  top: 0;\n  left: 0;\n\n  width: 100%;\n  height: 3px;\n\n  background:\n    linear-gradient(\n      90deg,\n      var(--gold),\n      #dfbd7c,\n      var(--gold)\n    );\n\n}\n\n\n\/* =========================================================\n   BACK\n========================================================= *\/\n\n#ss-rm-app-header\n.ss-rm-app-back {\n\n  min-height: 54px;\n\n  padding:\n    6px 10px\n    6px 6px;\n\n  display: flex;\n\n  align-items: center;\n\n  gap: 9px;\n\n  color:\n    var(--text);\n\n  text-decoration: none;\n\n  background:\n    var(--soft);\n\n  border:\n    1px solid\n    var(--border);\n\n  border-radius:\n    11px;\n\n  transition:\n    .18s ease;\n\n}\n\n\n#ss-rm-app-header\n.ss-rm-app-back:hover {\n\n  transform:\n    translateY(-1px);\n\n  background:\n    #ffffff;\n\n  border-color:\n    #d5b781;\n\n}\n\n\n#ss-rm-app-header\n.ss-rm-app-back-icon {\n\n  width: 39px;\n  height: 39px;\n\n  flex:\n    0 0 39px;\n\n  display: flex;\n\n  align-items: center;\n\n  justify-content: center;\n\n  color: #ffffff;\n\n  background:\n    linear-gradient(\n      145deg,\n      var(--navy),\n      var(--navy-2)\n    );\n\n  border-radius:\n    9px;\n\n}\n\n\n#ss-rm-app-header\n.ss-rm-app-back-icon svg {\n\n  width: 19px;\n  height: 19px;\n\n  fill: none;\n\n  stroke:\n    currentColor;\n\n  stroke-width: 2;\n\n  stroke-linecap: round;\n  stroke-linejoin: round;\n\n}\n\n\n#ss-rm-app-header\n.ss-rm-app-back-copy {\n\n  display: flex;\n\n  flex-direction: column;\n\n  line-height: 1.12;\n\n}\n\n\n#ss-rm-app-header\n.ss-rm-app-back-copy small {\n\n  margin-bottom: 3px;\n\n  color:\n    var(--muted);\n\n  font-size: 8px;\n\n  font-weight: 700;\n\n  letter-spacing: .8px;\n\n  text-transform: uppercase;\n\n}\n\n\n#ss-rm-app-header\n.ss-rm-app-back-copy strong {\n\n  color:\n    var(--navy);\n\n  font-size: 11px;\n\n  font-weight: 800;\n\n}\n\n\n\/* =========================================================\n   TITLE\n========================================================= *\/\n\n#ss-rm-app-header\n.ss-rm-app-title {\n\n  min-width: 0;\n\n}\n\n\n#ss-rm-app-header\n.ss-rm-app-eyebrow {\n\n  display: block;\n\n  margin-bottom: 4px;\n\n  color:\n    var(--gold-dark);\n\n  font-size: 9px;\n\n  font-weight: 850;\n\n  letter-spacing: 1.6px;\n\n  text-transform: uppercase;\n\n}\n\n\n#ss-rm-app-header h1 {\n\n  margin: 0;\n\n  color:\n    var(--navy);\n\n  font-size:\n    clamp(\n      25px,\n      2.5vw,\n      34px\n    );\n\n  line-height: 1.05;\n\n  font-weight: 850;\n\n  letter-spacing: -.7px;\n\n}\n\n\n#ss-rm-app-header p {\n\n  margin:\n    6px 0 0;\n\n  color:\n    var(--muted);\n\n  font-size: 11px;\n\n}\n\n\n\/* =========================================================\n   DESTINATION\n========================================================= *\/\n\n#ss-rm-app-header\n.ss-rm-app-destination {\n\n  min-width: 136px;\n\n  min-height: 52px;\n\n  padding:\n    7px 10px;\n\n  display: flex;\n\n  align-items: center;\n\n  gap: 9px;\n\n  background:\n    #ffffff;\n\n  border:\n    1px solid\n    var(--border);\n\n  border-radius:\n    11px;\n\n}\n\n\n#ss-rm-app-header\n.ss-rm-app-location-icon {\n\n  width: 37px;\n  height: 37px;\n\n  flex:\n    0 0 37px;\n\n  display: flex;\n\n  align-items: center;\n\n  justify-content: center;\n\n  color:\n    var(--gold-dark);\n\n  background:\n    #fff8eb;\n\n  border-radius:\n    9px;\n\n}\n\n\n#ss-rm-app-header\n.ss-rm-app-location-icon svg {\n\n  width: 18px;\n  height: 18px;\n\n  fill: none;\n\n  stroke:\n    currentColor;\n\n  stroke-width: 1.8;\n\n  stroke-linecap: round;\n  stroke-linejoin: round;\n\n}\n\n\n#ss-rm-app-header\n.ss-rm-app-location-copy {\n\n  display: flex;\n\n  flex-direction: column;\n\n}\n\n\n#ss-rm-app-header\n.ss-rm-app-location-copy small {\n\n  margin-bottom: 2px;\n\n  color:\n    #8d98a3;\n\n  font-size: 7px;\n\n  font-weight: 800;\n\n  letter-spacing: .7px;\n\n  text-transform: uppercase;\n\n}\n\n\n#ss-rm-app-header\n.ss-rm-app-location-copy strong {\n\n  color:\n    var(--navy);\n\n  font-size: 11px;\n\n  font-weight: 850;\n\n}\n\n\n\/* =========================================================\n   MOBILE\n========================================================= *\/\n\n@media (max-width:700px) {\n\n  #ss-rm-app-header {\n\n    width:\n      calc(100% - 16px);\n\n    min-height: auto;\n\n    margin:\n      8px auto\n      7px;\n\n    padding:\n      12px;\n\n    grid-template-columns:\n      40px\n      minmax(0,1fr)\n      auto;\n\n    gap: 9px;\n\n    border-radius:\n      13px;\n\n  }\n\n\n  #ss-rm-app-header\n  .ss-rm-app-back {\n\n    width: 40px;\n    height: 40px;\n\n    min-height: 40px;\n\n    padding: 0;\n\n    justify-content: center;\n\n    background:\n      transparent;\n\n    border: 0;\n\n  }\n\n\n  #ss-rm-app-header\n  .ss-rm-app-back-icon {\n\n    width: 38px;\n    height: 38px;\n\n    flex-basis: 38px;\n\n  }\n\n\n  #ss-rm-app-header\n  .ss-rm-app-back-copy {\n\n    display: none;\n\n  }\n\n\n  #ss-rm-app-header\n  .ss-rm-app-title {\n\n    min-width: 0;\n\n  }\n\n\n  #ss-rm-app-header\n  .ss-rm-app-eyebrow {\n\n    margin-bottom: 2px;\n\n    font-size: 7px;\n\n  }\n\n\n  #ss-rm-app-header h1 {\n\n    overflow: hidden;\n\n    font-size: 17px;\n\n    line-height: 1.1;\n\n    text-overflow: ellipsis;\n\n    white-space: nowrap;\n\n  }\n\n\n  #ss-rm-app-header p {\n\n    display: none;\n\n  }\n\n\n  #ss-rm-app-header\n  .ss-rm-app-destination {\n\n    min-width: 0;\n\n    min-height: 38px;\n\n    padding: 4px 7px;\n\n    gap: 5px;\n\n  }\n\n\n  #ss-rm-app-header\n  .ss-rm-app-location-icon {\n\n    width: 29px;\n    height: 29px;\n\n    flex-basis: 29px;\n\n  }\n\n\n  #ss-rm-app-header\n  .ss-rm-app-location-icon svg {\n\n    width: 15px;\n    height: 15px;\n\n  }\n\n\n  #ss-rm-app-header\n  .ss-rm-app-location-copy small {\n\n    display: none;\n\n  }\n\n\n  #ss-rm-app-header\n  .ss-rm-app-location-copy strong {\n\n    font-size: 9px;\n\n  }\n\n}\n\n<\/style>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-3639e1f elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"3639e1f\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-defcb58\" data-id=\"defcb58\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-c745864 elementor-widget elementor-widget-html\" data-id=\"c745864\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<!-- =========================================================\n     SUNNYSIDE DMC SERVICES\n     ODS RIVIERA MAYA\n     OPTION 1 \u2014 OPERATIONS APP CONTROLLER\n========================================================= -->\n\n<div\n  id=\"ss-rm-operations-app\"\n  data-view=\"register\"\n>\n\n  <!-- =====================================================\n       NAVIGATION\n  ====================================================== -->\n\n  <div class=\"ss-rm-app-navigation\">\n\n\n    <!-- REGISTER -->\n\n    <button\n      type=\"button\"\n      class=\"ss-rm-app-tab active\"\n      data-view=\"register\"\n      aria-selected=\"true\"\n    >\n\n      <span class=\"ss-rm-tab-icon\">\n\n        <svg viewBox=\"0 0 24 24\">\n          <path d=\"M12 5v14\"><\/path>\n          <path d=\"M5 12h14\"><\/path>\n        <\/svg>\n\n      <\/span>\n\n\n      <span class=\"ss-rm-tab-copy\">\n\n        <strong>\n          Registrar ODS\n        <\/strong>\n\n        <small>\n          Crear orden de servicio\n        <\/small>\n\n      <\/span>\n\n    <\/button>\n\n\n    <!-- RECORDS -->\n\n    <button\n      type=\"button\"\n      class=\"ss-rm-app-tab\"\n      data-view=\"records\"\n      aria-selected=\"false\"\n    >\n\n      <span class=\"ss-rm-tab-icon\">\n\n        <svg viewBox=\"0 0 24 24\">\n          <path d=\"M6 4h12v16H6z\"><\/path>\n          <path d=\"M9 9h6\"><\/path>\n          <path d=\"M9 13h6\"><\/path>\n          <path d=\"M9 17h4\"><\/path>\n        <\/svg>\n\n      <\/span>\n\n\n      <span class=\"ss-rm-tab-copy\">\n\n        <strong>\n          Records\n        <\/strong>\n\n        <small>\n          Consultar \u00f3rdenes\n        <\/small>\n\n      <\/span>\n\n    <\/button>\n\n\n    <!-- SPACER -->\n\n    <div class=\"ss-rm-app-navigation-space\"><\/div>\n\n\n    <!-- RELOAD -->\n\n    <button\n      type=\"button\"\n      class=\"ss-rm-app-reload\"\n      id=\"ss-rm-app-reload\"\n      aria-label=\"Recargar contenido\"\n    >\n\n      <svg viewBox=\"0 0 24 24\">\n        <path d=\"M20 11a8 8 0 1 0-2.3 5.7\"><\/path>\n        <path d=\"M20 4v7h-7\"><\/path>\n      <\/svg>\n\n      <span>\n        Recargar\n      <\/span>\n\n    <\/button>\n\n  <\/div>\n\n\n\n  <!-- =====================================================\n       FRAME\n  ====================================================== -->\n\n  <div\n    class=\"ss-rm-app-frame-shell is-loading\"\n    id=\"ss-rm-app-frame-shell\"\n  >\n\n\n    <!-- LOADER -->\n\n    <div class=\"ss-rm-app-loader\">\n\n      <div class=\"ss-rm-app-spinner\"><\/div>\n\n      <div>\n\n        <strong>\n          Cargando\n        <\/strong>\n\n        <span id=\"ss-rm-app-loading-text\">\n          Preparando formulario...\n        <\/span>\n\n      <\/div>\n\n    <\/div>\n\n\n    <!-- APPS SCRIPT -->\n\n    <iframe\n      id=\"ss-rm-app-frame\"\n      class=\"ss-rm-app-frame\"\n      src=\"about:blank\"\n      title=\"Sunnyside ODS Riviera Maya\"\n      loading=\"eager\"\n    ><\/iframe>\n\n  <\/div>\n\n<\/div>\n\n\n<style>\n\n\/* =========================================================\n   ROOT\n========================================================= *\/\n\n#ss-rm-operations-app,\n#ss-rm-operations-app * {\n  box-sizing: border-box;\n}\n\n\n#ss-rm-operations-app {\n\n  --navy: #071d34;\n  --navy-2: #0c2b49;\n\n  --gold: #c39a57;\n  --gold-dark: #a67b3e;\n\n  --white: #ffffff;\n\n  --bg: #f4f6f8;\n  --soft: #f7f9fb;\n\n  --text: #18212f;\n  --muted: #707d8b;\n\n  --border: #e0e6ec;\n\n  width:\n    min(\n      calc(100% - 32px),\n      1500px\n    );\n\n  margin:\n    0 auto\n    32px;\n\n  font-family:\n    Arial,\n    Helvetica,\n    sans-serif;\n\n}\n\n\n\/* =========================================================\n   NAVIGATION\n========================================================= *\/\n\n#ss-rm-operations-app\n.ss-rm-app-navigation {\n\n  min-height: 66px;\n\n  padding: 6px;\n\n  display: flex;\n\n  align-items: center;\n\n  gap: 6px;\n\n  background:\n    #ffffff;\n\n  border:\n    1px solid\n    var(--border);\n\n  border-radius:\n    14px;\n\n  box-shadow:\n    0 6px 18px\n    rgba(7,29,52,.04);\n\n}\n\n\n\/* =========================================================\n   TABS\n========================================================= *\/\n\n#ss-rm-operations-app\n.ss-rm-app-tab {\n\n  min-width: 180px;\n  min-height: 52px;\n\n  padding:\n    6px 13px\n    6px 7px;\n\n  display: flex;\n\n  align-items: center;\n\n  gap: 9px;\n\n  color:\n    var(--muted);\n\n  background:\n    transparent;\n\n  border:\n    1px solid\n    transparent;\n\n  border-radius:\n    10px;\n\n  font-family: inherit;\n\n  text-align: left;\n\n  cursor: pointer;\n\n  transition:\n    .18s ease;\n\n}\n\n\n#ss-rm-operations-app\n.ss-rm-app-tab:hover {\n\n  color:\n    var(--navy);\n\n  background:\n    var(--soft);\n\n}\n\n\n#ss-rm-operations-app\n.ss-rm-app-tab.active {\n\n  color:\n    #ffffff;\n\n  background:\n    linear-gradient(\n      145deg,\n      var(--navy),\n      var(--navy-2)\n    );\n\n  border-color:\n    var(--navy);\n\n  box-shadow:\n    0 6px 14px\n    rgba(7,29,52,.13);\n\n}\n\n\n#ss-rm-operations-app\n.ss-rm-tab-icon {\n\n  width: 37px;\n  height: 37px;\n\n  flex:\n    0 0 37px;\n\n  display: flex;\n\n  align-items: center;\n\n  justify-content: center;\n\n  color:\n    var(--navy);\n\n  background:\n    #eef3f7;\n\n  border-radius:\n    8px;\n\n}\n\n\n#ss-rm-operations-app\n.ss-rm-app-tab.active\n.ss-rm-tab-icon {\n\n  color:\n    #ffffff;\n\n  background:\n    rgba(255,255,255,.13);\n\n}\n\n\n#ss-rm-operations-app\n.ss-rm-tab-icon svg {\n\n  width: 17px;\n  height: 17px;\n\n  fill: none;\n\n  stroke:\n    currentColor;\n\n  stroke-width: 2;\n\n  stroke-linecap: round;\n  stroke-linejoin: round;\n\n}\n\n\n#ss-rm-operations-app\n.ss-rm-tab-copy {\n\n  min-width: 0;\n\n  display: flex;\n\n  flex-direction: column;\n\n  gap: 2px;\n\n}\n\n\n#ss-rm-operations-app\n.ss-rm-tab-copy strong {\n\n  color:\n    inherit;\n\n  font-size: 11px;\n\n  font-weight: 800;\n\n}\n\n\n#ss-rm-operations-app\n.ss-rm-tab-copy small {\n\n  color:\n    #8b96a1;\n\n  font-size: 8px;\n\n}\n\n\n#ss-rm-operations-app\n.ss-rm-app-tab.active\n.ss-rm-tab-copy small {\n\n  color:\n    rgba(255,255,255,.68);\n\n}\n\n\n\/* =========================================================\n   RELOAD\n========================================================= *\/\n\n#ss-rm-operations-app\n.ss-rm-app-navigation-space {\n  flex: 1;\n}\n\n\n#ss-rm-operations-app\n.ss-rm-app-reload {\n\n  min-height: 40px;\n\n  padding:\n    8px 11px;\n\n  display: flex;\n\n  align-items: center;\n\n  justify-content: center;\n\n  gap: 6px;\n\n  color:\n    var(--navy);\n\n  background:\n    #ffffff;\n\n  border:\n    1px solid\n    var(--border);\n\n  border-radius:\n    9px;\n\n  font-family: inherit;\n\n  font-size: 9px;\n\n  font-weight: 750;\n\n  cursor: pointer;\n\n}\n\n\n#ss-rm-operations-app\n.ss-rm-app-reload:hover {\n\n  background:\n    #fff8ec;\n\n  border-color:\n    #d8bd91;\n\n}\n\n\n#ss-rm-operations-app\n.ss-rm-app-reload svg {\n\n  width: 15px;\n  height: 15px;\n\n  fill: none;\n\n  stroke:\n    currentColor;\n\n  stroke-width: 1.9;\n\n  stroke-linecap: round;\n  stroke-linejoin: round;\n\n}\n\n\n\/* =========================================================\n   FRAME\n========================================================= *\/\n\n#ss-rm-operations-app\n.ss-rm-app-frame-shell {\n\n  position: relative;\n\n  width: 100%;\n\n  margin-top: 8px;\n\n  overflow: hidden;\n\n  background:\n    var(--bg);\n\n  border:\n    1px solid\n    var(--border);\n\n  border-radius:\n    15px;\n\n  box-shadow:\n    0 7px 22px\n    rgba(7,29,52,.035);\n\n}\n\n\n#ss-rm-operations-app\n.ss-rm-app-frame {\n\n  width: 100%;\n\n  height: 1370px;\n\n  display: block;\n\n  border: 0;\n\n  background:\n    var(--bg);\n\n  transition:\n    opacity .2s ease;\n\n}\n\n\n#ss-rm-operations-app[\n  data-view=\"records\"\n]\n.ss-rm-app-frame {\n\n  height: 1250px;\n\n}\n\n\n\/* =========================================================\n   LOADER\n========================================================= *\/\n\n#ss-rm-operations-app\n.ss-rm-app-loader {\n\n  position: absolute;\n\n  z-index: 10;\n\n  inset: 0;\n\n  padding-top: 70px;\n\n  display: flex;\n\n  align-items: flex-start;\n\n  justify-content: center;\n\n  gap: 10px;\n\n  color:\n    var(--text);\n\n  background:\n    rgba(244,246,248,.97);\n\n  opacity: 0;\n\n  visibility: hidden;\n\n  pointer-events: none;\n\n}\n\n\n#ss-rm-operations-app\n.ss-rm-app-frame-shell.is-loading\n.ss-rm-app-loader {\n\n  opacity: 1;\n\n  visibility: visible;\n\n  pointer-events: auto;\n\n}\n\n\n#ss-rm-operations-app\n.ss-rm-app-frame-shell.is-loading\n.ss-rm-app-frame {\n\n  opacity: .15;\n\n}\n\n\n#ss-rm-operations-app\n.ss-rm-app-spinner {\n\n  width: 25px;\n  height: 25px;\n\n  border:\n    3px solid\n    #dfe4e9;\n\n  border-top-color:\n    var(--navy);\n\n  border-radius: 50%;\n\n  animation:\n    ssRmSpin\n    .8s linear\n    infinite;\n\n}\n\n\n#ss-rm-operations-app\n.ss-rm-app-loader > div:last-child {\n\n  display: flex;\n\n  flex-direction: column;\n\n  gap: 3px;\n\n}\n\n\n#ss-rm-operations-app\n.ss-rm-app-loader strong {\n\n  color:\n    var(--navy);\n\n  font-size: 11px;\n\n}\n\n\n#ss-rm-operations-app\n.ss-rm-app-loader span {\n\n  color:\n    var(--muted);\n\n  font-size: 9px;\n\n}\n\n\n@keyframes ssRmSpin {\n\n  to {\n    transform:\n      rotate(360deg);\n  }\n\n}\n\n\n\/* =========================================================\n   MOBILE\n========================================================= *\/\n\n@media (max-width:600px) {\n\n  #ss-rm-operations-app {\n\n    width:\n      calc(100% - 10px);\n\n    margin-bottom:\n      18px;\n\n  }\n\n\n  #ss-rm-operations-app\n  .ss-rm-app-navigation {\n\n    min-height: 57px;\n\n    padding: 4px;\n\n    gap: 4px;\n\n    border-radius:\n      11px;\n\n  }\n\n\n  #ss-rm-operations-app\n  .ss-rm-app-tab {\n\n    flex: 1;\n\n    min-width: 0;\n\n    min-height: 47px;\n\n    padding:\n      5px 7px;\n\n    justify-content: center;\n\n  }\n\n\n  #ss-rm-operations-app\n  .ss-rm-tab-icon {\n\n    width: 31px;\n    height: 31px;\n\n    flex-basis: 31px;\n\n  }\n\n\n  #ss-rm-operations-app\n  .ss-rm-tab-copy strong {\n\n    font-size: 9px;\n\n  }\n\n\n  #ss-rm-operations-app\n  .ss-rm-tab-copy small {\n\n    display: none;\n\n  }\n\n\n  #ss-rm-operations-app\n  .ss-rm-app-navigation-space {\n\n    display: none;\n\n  }\n\n\n  #ss-rm-operations-app\n  .ss-rm-app-reload {\n\n    width: 38px;\n    height: 38px;\n\n    min-height: 38px;\n\n    padding: 0;\n\n    flex:\n      0 0 38px;\n\n  }\n\n\n  #ss-rm-operations-app\n  .ss-rm-app-reload span {\n\n    display: none;\n\n  }\n\n\n  #ss-rm-operations-app\n  .ss-rm-app-frame-shell {\n\n    margin-top: 6px;\n\n    border-radius:\n      11px;\n\n  }\n\n\n  #ss-rm-operations-app\n  .ss-rm-app-frame {\n\n    height: 1700px;\n\n  }\n\n\n  #ss-rm-operations-app[\n    data-view=\"records\"\n  ]\n  .ss-rm-app-frame {\n\n    height: 1480px;\n\n  }\n\n}\n\n<\/style>\n\n\n<script>\n\n(function () {\n\n  \"use strict\";\n\n\n  const APPS_SCRIPT_URL =\n    \"https:\/\/script.google.com\/macros\/s\/AKfycbxmiyUSvYGJ58WRMxUSQf0rFXpOheOuPnxrM0Kcq2tBZmEhc8Fiuyk4-2XgYmWsPZ6n3Q\/exec\";\n\n\n  const TOKEN_ENDPOINT =\n    \"\/wp-admin\/admin-ajax.php?action=ss_ods_rm_token\";\n\n\n  const EXPECTED_MODULE =\n    \"ods-rm\";\n\n\n  const app =\n    document.getElementById(\n      \"ss-rm-operations-app\"\n    );\n\n\n  if (!app) {\n    return;\n  }\n\n\n  const frame =\n    document.getElementById(\n      \"ss-rm-app-frame\"\n    );\n\n\n  const frameShell =\n    document.getElementById(\n      \"ss-rm-app-frame-shell\"\n    );\n\n\n  const loadingText =\n    document.getElementById(\n      \"ss-rm-app-loading-text\"\n    );\n\n\n  const reload =\n    document.getElementById(\n      \"ss-rm-app-reload\"\n    );\n\n\n  const tabs =\n    app.querySelectorAll(\n      \".ss-rm-app-tab\"\n    );\n\n\n  const views = {\n\n    register: {\n\n      page:\n        \"\",\n\n      loading:\n        \"Preparando formulario...\"\n\n    },\n\n    records: {\n\n      page:\n        \"search\",\n\n      loading:\n        \"Cargando records...\"\n\n    }\n\n  };\n\n\n  let cachedToken =\n    \"\";\n\n\n  let cachedTokenExp =\n    0;\n\n\n  let loadSequence =\n    0;\n\n\n  function showLoading() {\n\n    frameShell.classList.add(\n      \"is-loading\"\n    );\n\n  }\n\n\n  function hideLoading() {\n\n    frameShell.classList.remove(\n      \"is-loading\"\n    );\n\n  }\n\n\n  function setActiveTab(\n    viewName\n  ) {\n\n    app.dataset.view =\n      viewName;\n\n\n    tabs.forEach(\n      function (tab) {\n\n        const active =\n          tab.dataset.view ===\n          viewName;\n\n\n        tab.classList.toggle(\n          \"active\",\n          active\n        );\n\n\n        tab.setAttribute(\n          \"aria-selected\",\n          active\n            ? \"true\"\n            : \"false\"\n        );\n\n      }\n    );\n\n  }\n\n\n  function decodeTokenPayload(\n    token\n  ) {\n\n    try {\n\n      const parts =\n        String(\n          token || \"\"\n        ).split(\".\");\n\n\n      if (\n        parts.length !== 2 ||\n        !parts[0]\n      ) {\n        return null;\n      }\n\n\n      let payload =\n        parts[0]\n          .replace(\n            \/-\/g,\n            \"+\"\n          )\n          .replace(\n            \/_\/g,\n            \"\/\"\n          );\n\n\n      while (\n        payload.length % 4\n      ) {\n\n        payload += \"=\";\n\n      }\n\n\n      const binary =\n        window.atob(\n          payload\n        );\n\n\n      const bytes =\n        Uint8Array.from(\n          binary,\n          function (character) {\n\n            return character.charCodeAt(\n              0\n            );\n\n          }\n        );\n\n\n      const json =\n        new TextDecoder(\n          \"utf-8\"\n        ).decode(\n          bytes\n        );\n\n\n      return JSON.parse(\n        json\n      );\n\n    } catch (error) {\n\n      return null;\n\n    }\n\n  }\n\n\n  function tokenIsUsable() {\n\n    if (!cachedToken) {\n      return false;\n    }\n\n\n    const now =\n      Math.floor(\n        Date.now() \/ 1000\n      );\n\n\n    return (\n      cachedTokenExp >\n      now + 60\n    );\n\n  }\n\n\n  async function getAuthorizationToken(\n    forceRefresh\n  ) {\n\n    if (\n      !forceRefresh &&\n      tokenIsUsable()\n    ) {\n\n      return cachedToken;\n\n    }\n\n\n    const response =\n      await fetch(\n        TOKEN_ENDPOINT,\n        {\n          method:\n            \"GET\",\n\n          credentials:\n            \"same-origin\",\n\n          cache:\n            \"no-store\",\n\n          headers: {\n            \"Accept\":\n              \"application\/json\"\n          }\n        }\n      );\n\n\n    const responseText =\n      await response.text();\n\n\n    let payload =\n      null;\n\n\n    try {\n\n      payload =\n        JSON.parse(\n          responseText\n        );\n\n    } catch (error) {\n\n      payload =\n        null;\n\n    }\n\n\n    if (\n      !response.ok ||\n      !payload ||\n      payload.success !== true ||\n      !payload.data ||\n      !payload.data.token\n    ) {\n\n      throw new Error(\n        \"No se pudo obtener autorizaci\u00f3n para ODS Riviera Maya.\"\n      );\n\n    }\n\n\n    if (\n      String(\n        payload.data.module || \"\"\n      ) !==\n      EXPECTED_MODULE\n    ) {\n\n      throw new Error(\n        \"La autorizaci\u00f3n recibida no corresponde a ODS Riviera Maya.\"\n      );\n\n    }\n\n\n    const token =\n      String(\n        payload.data.token\n      );\n\n\n    const tokenPayload =\n      decodeTokenPayload(\n        token\n      );\n\n\n    if (\n      !tokenPayload ||\n      String(\n        tokenPayload.module || \"\"\n      ) !==\n      EXPECTED_MODULE\n    ) {\n\n      throw new Error(\n        \"Token de autorizaci\u00f3n inv\u00e1lido.\"\n      );\n\n    }\n\n\n    cachedToken =\n      token;\n\n\n    cachedTokenExp =\n      Number(\n        tokenPayload.exp || 0\n      );\n\n\n    return cachedToken;\n\n  }\n\n\n  function buildAppUrl(\n    viewName,\n    token\n  ) {\n\n    const view =\n      views[\n        viewName\n      ];\n\n\n    if (!view) {\n\n      throw new Error(\n        \"Vista no v\u00e1lida.\"\n      );\n\n    }\n\n\n    const url =\n      new URL(\n        APPS_SCRIPT_URL\n      );\n\n\n    if (\n      view.page\n    ) {\n\n      url.searchParams.set(\n        \"page\",\n        view.page\n      );\n\n    }\n\n\n    url.searchParams.set(\n      \"token\",\n      token\n    );\n\n\n    return url.toString();\n\n  }\n\n\n  function showAuthorizationError(\n    error\n  ) {\n\n    hideLoading();\n\n\n    const message =\n      error &&\n      error.message\n        ? String(\n            error.message\n          )\n        : \"No se pudo cargar ODS Riviera Maya.\";\n\n\n    frame.src =\n      \"about:blank\";\n\n\n    frame.srcdoc =\n      '<!DOCTYPE html>' +\n      '<html lang=\"es\">' +\n      '<head>' +\n      '<meta charset=\"UTF-8\">' +\n      '<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">' +\n      '<style>' +\n      'html,body{margin:0;min-height:100%;background:#f4f6f8;font-family:Arial,Helvetica,sans-serif;}' +\n      'body{min-height:100vh;display:flex;align-items:flex-start;justify-content:center;padding:40px 18px;box-sizing:border-box;}' +\n      '.card{width:100%;max-width:560px;padding:24px;box-sizing:border-box;background:#fff;border:1px solid #e0e6ec;border-radius:14px;box-shadow:0 7px 22px rgba(7,29,52,.04);}' +\n      'h3{margin:0 0 8px;color:#071d34;font-size:17px;}' +\n      'p{margin:0;color:#707d8b;font-size:13px;line-height:1.55;}' +\n      '<\/style>' +\n      '<\/head>' +\n      '<body>' +\n      '<div class=\"card\">' +\n      '<h3>No se pudo cargar ODS Riviera Maya<\/h3>' +\n      '<p>' +\n      escapeHtml(\n        message\n      ) +\n      '<\/p>' +\n      '<\/div>' +\n      '<\/body>' +\n      '<\/html>';\n\n  }\n\n\n  function escapeHtml(\n    value\n  ) {\n\n    return String(\n      value || \"\"\n    )\n      .replace(\n        \/&\/g,\n        \"&amp;\"\n      )\n      .replace(\n        \/<\/g,\n        \"&lt;\"\n      )\n      .replace(\n        \/>\/g,\n        \"&gt;\"\n      )\n      .replace(\n        \/\"\/g,\n        \"&quot;\"\n      )\n      .replace(\n        \/'\/g,\n        \"&#039;\"\n      );\n\n  }\n\n\n  async function loadView(\n    viewName,\n    forceRefresh\n  ) {\n\n    const view =\n      views[\n        viewName\n      ];\n\n\n    if (!view) {\n      return;\n    }\n\n\n    const currentLoad =\n      ++loadSequence;\n\n\n    setActiveTab(\n      viewName\n    );\n\n\n    loadingText.textContent =\n      view.loading;\n\n\n    showLoading();\n\n\n    try {\n\n      const token =\n        await getAuthorizationToken(\n          Boolean(\n            forceRefresh\n          )\n        );\n\n\n      if (\n        currentLoad !==\n        loadSequence\n      ) {\n        return;\n      }\n\n\n      frame.removeAttribute(\n        \"srcdoc\"\n      );\n\n\n      frame.src =\n        buildAppUrl(\n          viewName,\n          token\n        );\n\n    } catch (error) {\n\n      if (\n        currentLoad !==\n        loadSequence\n      ) {\n        return;\n      }\n\n\n      showAuthorizationError(\n        error\n      );\n\n    }\n\n  }\n\n\n  tabs.forEach(\n    function (tab) {\n\n      tab.addEventListener(\n        \"click\",\n        function () {\n\n          loadView(\n            tab.dataset.view,\n            false\n          );\n\n        }\n      );\n\n    }\n  );\n\n\n  frame.addEventListener(\n    \"load\",\n    function () {\n\n      if (\n        frame.getAttribute(\n          \"src\"\n        ) ===\n        \"about:blank\"\n      ) {\n        return;\n      }\n\n\n      window.setTimeout(\n        hideLoading,\n        220\n      );\n\n    }\n  );\n\n\n  reload.addEventListener(\n    \"click\",\n    function () {\n\n      cachedToken =\n        \"\";\n\n\n      cachedTokenExp =\n        0;\n\n\n      loadView(\n        app.dataset.view ||\n        \"register\",\n        true\n      );\n\n    }\n  );\n\n\n  loadView(\n    \"register\",\n    false\n  );\n\n})();\n\n<\/script>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Volver a Central de Reservas Service Orders ODS Riviera Maya Generaci\u00f3n y administraci\u00f3n de \u00f3rdenes de servicio. Destination CUN \/ RM Registrar ODS Crear orden de servicio Records Consultar \u00f3rdenes Recargar Cargando Preparando formulario&#8230;<\/p>","protected":false},"author":7,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_canvas","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"class_list":["post-14164","page","type-page","status-publish","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/sunnyside.com.mx\/es\/wp-json\/wp\/v2\/pages\/14164","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sunnyside.com.mx\/es\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/sunnyside.com.mx\/es\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/sunnyside.com.mx\/es\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/sunnyside.com.mx\/es\/wp-json\/wp\/v2\/comments?post=14164"}],"version-history":[{"count":44,"href":"https:\/\/sunnyside.com.mx\/es\/wp-json\/wp\/v2\/pages\/14164\/revisions"}],"predecessor-version":[{"id":16174,"href":"https:\/\/sunnyside.com.mx\/es\/wp-json\/wp\/v2\/pages\/14164\/revisions\/16174"}],"wp:attachment":[{"href":"https:\/\/sunnyside.com.mx\/es\/wp-json\/wp\/v2\/media?parent=14164"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}