{"id":1257,"date":"2026-09-02T16:14:20","date_gmt":"2026-09-02T14:14:20","guid":{"rendered":"https:\/\/onode.es\/services\/software\/"},"modified":"2026-10-01T12:41:04","modified_gmt":"2026-10-01T10:41:04","slug":"software","status":"publish","type":"page","link":"https:\/\/onode.es\/en\/services\/software\/","title":{"rendered":"Software"},"content":{"rendered":"<div class=\"et_pb_section_0 et_pb_section et_section_regular et_block_section et_animated hero-manchas onode-fluid-section\">\n<div class=\"et_pb_row_0 et_pb_row et_block_row\">\n<div class=\"et_pb_column_0 et_pb_column et_pb_column_4_4 et-last-child et_block_column et_pb_css_mix_blend_mode_passthrough\">\n<div class=\"et_pb_code_0 et_pb_code et_pb_module\"><div class=\"et_pb_code_inner\"><!-- ============================================================\n  EFECTO MANCHAS ANIMADAS \u2014 onode.thelab.es\n  Pegar en un m\u00f3dulo \"C\u00f3digo\" de Divi dentro de la secci\u00f3n hero.\n  La secci\u00f3n debe tener la clase CSS personalizada: hero-manchas\n  ============================================================ --><style id=\"blob-style\">.hero-manchas {\n    position: fixed !important;\n    overflow: hidden !important;\n    top: 0px!important;\n  }\n  #blob-canvas-wrapper {\n    position: absolute;\n    inset: 0;\n    pointer-events: none;\n    z-index: 0;\n  }\n  \/* Degradado inferior hacia blanco *\/\n  #blob-canvas-wrapper::after {\n    content: '';\n    position: absolute;\n    bottom: 0; left: 0; right: 0;\n    height: 45%;\n    \/*background: linear-gradient(to bottom, transparent, #91C0DB);*\/\n    pointer-events: none;\n    z-index: 2;\n  }\n  #blob-canvas {\n    width: 100%;\n    height: 100%;\n    display: block;\n    filter: blur(72px) saturate(1.4);\n  }\n  .hero-manchas > *:not(#blob-canvas-wrapper) {\n    position: relative;\n    z-index: 1;\n  }\n<\/style><script>(function () {\n  function initBlobs() {\n    var hero = document.querySelector('.hero-manchas');\n    if (!hero || document.getElementById('blob-canvas-wrapper')) return;\n \n    \/* --- Canvas --- *\/\n    var wrapper = document.createElement('div');\n    wrapper.id = 'blob-canvas-wrapper';\n    var canvas = document.createElement('canvas');\n    canvas.id = 'blob-canvas';\n    wrapper.appendChild(canvas);\n    hero.insertBefore(wrapper, hero.firstChild);\n \n    var ctx = canvas.getContext('2d');\n    var W, H;\n    function resize() { W = canvas.width = hero.offsetWidth; H = canvas.height = hero.offsetHeight; }\n    resize();\n    window.addEventListener('resize', resize);\n \n    \/* --- Rat\u00f3n: solo activo mientras se mueve --- *\/\n    var mouse = { x: 0, y: 0, active: false };\n    var mouseTimer = null;\n    document.addEventListener('mousemove', function (e) {\n      var rect = hero.getBoundingClientRect();\n      mouse.x = e.clientX - rect.left;\n      mouse.y = e.clientY - rect.top;\n      mouse.active = true;\n      clearTimeout(mouseTimer);\n      mouseTimer = setTimeout(function () { mouse.active = false; }, 300);\n    });\n \n    \/* --- Manchas --- *\/\n    var blobs = [\n      {\n        x: W * 0.28, y: H * 0.45,\n        vx: 1.1, vy: 0.75,\n        r: 680,\n        color: [50, 85, 114], alpha: 0.82,\n        ox: [{ a: 1.4, f: 0.009 }, { a: 0.7, f: 0.017 }],\n        oy: [{ a: 1.0, f: 0.007 }, { a: 0.8, f: 0.013 }],\n        phase: 0,\n        attract: 0.008\n      },\n      {\n        x: W * 0.68, y: H * 0.52,\n        vx: -0.9, vy: 0.85,\n        r: 600,\n        color: [145, 192, 219], alpha: 0.78,\n        ox: [{ a: 1.2, f: 0.008 }, { a: 0.7, f: 0.015 }],\n        oy: [{ a: 1.1, f: 0.011 }, { a: 0.6, f: 0.006 }],\n        phase: 2.5,\n        attract: 0.007\n      }\n    ];\n \n    function drawBlob(b) {\n      var r = b.color[0], g = b.color[1], bl = b.color[2];\n      var grad = ctx.createRadialGradient(b.x, b.y, 0, b.x, b.y, b.r);\n      grad.addColorStop(0,   'rgba('+r+','+g+','+bl+','+b.alpha+')');\n      grad.addColorStop(0.5, 'rgba('+r+','+g+','+bl+','+(b.alpha*0.45)+')');\n      grad.addColorStop(1,   'rgba('+r+','+g+','+bl+',0)');\n      ctx.beginPath();\n      ctx.arc(b.x, b.y, b.r, 0, Math.PI * 2);\n      ctx.fillStyle = grad;\n      ctx.fill();\n    }\n \n    var t = 0;\n    function animate() {\n      t++;\n      ctx.clearRect(0, 0, W, H);\n \n      blobs.forEach(function (b) {\n        \/* Movimiento aut\u00f3nomo: velocidad base + oscilaciones en capas *\/\n        var driftX = b.ox.reduce(function (s, o) { return s + Math.sin(t * o.f + b.phase) * o.a; }, 0);\n        var driftY = b.oy.reduce(function (s, o) { return s + Math.cos(t * o.f + b.phase) * o.a; }, 0);\n        b.x += b.vx + driftX;\n        b.y += b.vy + driftY;\n \n        \/* Atracci\u00f3n solo cuando el rat\u00f3n se est\u00e1 moviendo *\/\n        if (mouse.active) {\n          b.x += (mouse.x - b.x) * b.attract;\n          b.y += (mouse.y - b.y) * b.attract;\n        }\n \n        \/* Rebote suave en bordes *\/\n        var m = b.r * 0.2;\n        if (b.x < m)     { b.x = m;     b.vx =  Math.abs(b.vx); }\n        if (b.x > W - m) { b.x = W - m; b.vx = -Math.abs(b.vx); }\n        if (b.y < m)     { b.y = m;     b.vy =  Math.abs(b.vy); }\n        if (b.y > H - m) { b.y = H - m; b.vy = -Math.abs(b.vy); }\n \n        drawBlob(b);\n      });\n \n      requestAnimationFrame(animate);\n    }\n    animate();\n  }\n \n  if (document.readyState === 'loading') {\n    document.addEventListener('DOMContentLoaded', initBlobs);\n  } else {\n    initBlobs();\n  }\n})();\n<\/script><\/div><\/div>\n<\/div>\n<\/div>\n<\/div>\n\n<div class=\"et_pb_section_1 et_pb_section et_section_regular et_flex_section\">\n<div class=\"et_pb_row_1 et_pb_row et_block_row\">\n<div class=\"et_pb_column_1 et_pb_column et_pb_column_4_4 et-last-child et_flex_column et_pb_css_mix_blend_mode_passthrough\">\n<div class=\"et_pb_text_0 et_pb_text et_pb_bg_layout_light et_pb_module et_flex_module\"><div class=\"et_pb_text_inner\"><p>Service<\/p>\n<\/div><\/div>\n\n<div class=\"et_pb_text_1 et_pb_text et_pb_bg_layout_light et_pb_module et_flex_module\"><div class=\"et_pb_text_inner\"><p>Software on Demand<\/p>\n<\/div><\/div>\n<\/div>\n<\/div>\n<\/div>\n\n<div class=\"et_pb_section_2 et_pb_section et_section_regular et_block_section\">\n<div class=\"et_pb_row_2 et_pb_row et_flex_row\">\n<div class=\"et_pb_column_2 et_pb_column et-last-child et_block_column et_pb_css_mix_blend_mode_passthrough et_flex_column_24_24 et_flex_column_24_24_tablet et_flex_column_24_24_phone\">\n<div class=\"et_pb_text_2 et_pb_text et_pb_bg_layout_light et_pb_module et_flex_module\"><div class=\"et_pb_text_inner\"><p><span>Custom technology solutions for specific needs<\/span><\/p>\n<\/div><\/div>\n\n<div class=\"et_pb_text_3 et_pb_text et_pb_bg_layout_light et_pb_module et_flex_module\"><div class=\"et_pb_text_inner\"><p style=\"text-align: justify;\"><span>Not all of an organization's needs fit into a standard solution. That's why, alongside our specialized platforms, we offer <strong>Software on Demand<\/strong>: an open service in which we accompany the entity in the <strong>conceptualization and development of highly customized software projects<\/strong>, designed to meet the exclusive operational needs of each area, department, or entity. <\/span><\/p>\n<p style=\"text-align: justify;\"><span>From the initial idea to launch, we work hand in hand with technical teams and functional leads to build the solution they really need, nothing more, nothing less.<\/span><\/p>\n<\/div><\/div>\n<\/div>\n<\/div>\n<\/div>\n\n<div class=\"et_pb_section_3 et_pb_section et_section_regular et_flex_section\">\n<div class=\"et_pb_row_3 et_pb_row et_flex_row\">\n<div class=\"et_pb_column_3 et_pb_column et-last-child et_flex_column et_pb_css_mix_blend_mode_passthrough et_flex_column_24_24 et_flex_column_24_24_tablet et_flex_column_24_24_phone\">\n<div class=\"et_pb_text_4 et_pb_text et_pb_bg_layout_light et_pb_module et_flex_module\"><div class=\"et_pb_text_inner\"><p><span>What the service includes<\/span><\/p>\n<\/div><\/div>\n\n<div class=\"et_pb_code_1 et_pb_code et_pb_module\"><div class=\"et_pb_code_inner\"><link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\n<link rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin>\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Outfit:wght@300;400;500;600;700&display=swap\" rel=\"stylesheet\">\n\n<div class=\"onode-desarrollo\">\n\n  <!-- FOTO (solo en ordenador) -->\n  <div class=\"onode-desarrollo__media\">\n    <div class=\"onode-desarrollo__photo\">\n              <img class=\"onode-desa-photo is-active\" data-index=\"0\" loading=\"eager\" decoding=\"async\" fetchpriority=\"high\" src=\"https:\/\/onode.es\/wp-content\/uploads\/2026\/10\/Desenvolupament-a-Mida-scaled.jpeg\" alt=\"Custom Development\" style=\"object-position: center bottom;\">\n              <img class=\"onode-desa-photo\" data-index=\"1\" loading=\"eager\" decoding=\"async\" src=\"https:\/\/onode.es\/wp-content\/uploads\/2026\/10\/TI-impulsada-per-IA-scaled.jpeg\" alt=\"AI-Powered IT\" style=\"object-position: center top;\">\n              <img class=\"onode-desa-photo\" data-index=\"2\" loading=\"eager\" decoding=\"async\" src=\"https:\/\/onode.es\/wp-content\/uploads\/2026\/10\/Integracio-de-Sistemes-i-Interoperabilitat-scaled.jpeg\" alt=\"Systems Integration and Interoperability\" style=\"object-position: center top;\">\n              <img class=\"onode-desa-photo\" data-index=\"3\" loading=\"eager\" decoding=\"async\" src=\"https:\/\/onode.es\/wp-content\/uploads\/2026\/10\/Consultoria-Tecnologica-i-Experiencia-dUsuari-UX_UI-scaled.jpeg\" alt=\"Technology Consulting and User Experience (UX\/UI)\" style=\"object-position: center top;\">\n          <\/div>\n  <\/div>\n\n  <!-- ACORDE\u00d3N -->\n  <div class=\"onode-desarrollo__list\">\n          <div class=\"onode-desarrollo__item is-active\" data-index=\"0\" tabindex=\"0\" role=\"button\" aria-expanded=\"true\">\n        <div class=\"onode-desarrollo__head\">\n          <h3>Custom Development<\/h3>\n          <span class=\"onode-desarrollo__icon\" aria-hidden=\"true\"><\/span>\n        <\/div>\n        <div class=\"onode-desarrollo__desc\">\n          <div class=\"onode-desarrollo__desc-inner\">\n            <div class=\"onode-desarrollo__desc-text\">\n                              <p>Creation of applications and platforms fully tailored to the specific workflows of any organisation. No generic solutions: we start from how each area or department really works to build the tool that fits its day-to-day operations.<\/p>\n                          <\/div>\n          <\/div>\n        <\/div>\n      <\/div>\n          <div class=\"onode-desarrollo__item\" data-index=\"1\" tabindex=\"0\" role=\"button\" aria-expanded=\"false\">\n        <div class=\"onode-desarrollo__head\">\n          <h3>AI-Powered IT<\/h3>\n          <span class=\"onode-desarrollo__icon\" aria-hidden=\"true\"><\/span>\n        <\/div>\n        <div class=\"onode-desarrollo__desc\">\n          <div class=\"onode-desarrollo__desc-inner\">\n            <div class=\"onode-desarrollo__desc-text\">\n                              <p>We accelerate application development with generative and agentic AI that designs, generates code and automates testing and documentation. We also modernise legacy systems, eliminate technical debt and optimise IT maintenance and support with custom AI assistants.<\/p>\n                          <\/div>\n          <\/div>\n        <\/div>\n      <\/div>\n          <div class=\"onode-desarrollo__item\" data-index=\"2\" tabindex=\"0\" role=\"button\" aria-expanded=\"false\">\n        <div class=\"onode-desarrollo__head\">\n          <h3>Systems Integration and Interoperability<\/h3>\n          <span class=\"onode-desarrollo__icon\" aria-hidden=\"true\"><\/span>\n        <\/div>\n        <div class=\"onode-desarrollo__desc\">\n          <div class=\"onode-desarrollo__desc-inner\">\n            <div class=\"onode-desarrollo__desc-text\">\n                              <p>Connection of existing platforms with the main nodes and registers of the Public Administration, ensuring interoperability and avoiding duplication or information silos.<\/p>\n                          <\/div>\n          <\/div>\n        <\/div>\n      <\/div>\n          <div class=\"onode-desarrollo__item\" data-index=\"3\" tabindex=\"0\" role=\"button\" aria-expanded=\"false\">\n        <div class=\"onode-desarrollo__head\">\n          <h3>Technology Consulting and User Experience (UX\/UI)<\/h3>\n          <span class=\"onode-desarrollo__icon\" aria-hidden=\"true\"><\/span>\n        <\/div>\n        <div class=\"onode-desarrollo__desc\">\n          <div class=\"onode-desarrollo__desc-inner\">\n            <div class=\"onode-desarrollo__desc-text\">\n                              <p>Analysis of the real needs of employees and citizens to design usable, efficient interfaces with no barriers to entry. The best technology only adds value if the people who use it can do so without friction.<\/p>\n                          <\/div>\n          <\/div>\n        <\/div>\n      <\/div>\n      <\/div>\n<\/div>\n\n<style>\n.onode-desarrollo, .onode-desarrollo *, .onode-desarrollo *::before, .onode-desarrollo *::after {\n  box-sizing: border-box;\n}\n.onode-desarrollo {\n  --photo-min-height: 460px;\n  position: relative;\n  display: grid;\n  grid-template-columns: 0.9fr 1fr;\n  gap: 90px;\n  align-items: start;\n  width: 100%;\n  max-width: none;\n  margin: 0;\n  padding: 0;\n  font-family: 'Outfit', sans-serif;\n}\n\n\/* ---------- FOTO (ordenador) ---------- *\/\n\/* La altura la calcula el script: la del acorde\u00f3n con la descripci\u00f3n m\u00e1s larga abierta *\/\n.onode-desarrollo__photo {\n  position: relative;\n  height: var(--photo-min-height);\n  min-height: var(--photo-min-height);\n  border-radius: 19px;\n  overflow: hidden;\n  background: #dfe6ea;\n}\n.onode-desarrollo__photo img {\n  position: absolute;\n  inset: 0;\n  width: 100%;\n  height: 100%;\n  object-fit: cover;\n  object-position: top;\n  display: block;\n  margin: 0;\n  opacity: 0;\n}\n.onode-desarrollo__photo img.is-active {\n  opacity: 1;\n}\n.onode-desarrollo__photo::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  background-color: #335673;\n  opacity: 0.4;\n  mix-blend-mode: multiply;\n  pointer-events: none;\n  z-index: 1;\n}\n\n\/* ---------- ACORDE\u00d3N ---------- *\/\n\/* Centrado en vertical respecto a la foto *\/\n.onode-desarrollo__list {\n  position: relative;\n  z-index: 5;\n  align-self: center;\n  display: flex;\n  flex-direction: column;\n  margin-top: 0;\n  pointer-events: auto;\n}\n.onode-desarrollo__item {\n  position: relative;\n  padding: 28px 0;\n  border-bottom: 1px solid #c3d0d9;\n  cursor: pointer;\n  outline: none;\n  pointer-events: auto;\n  transition: border-color .25s ease;\n}\n.onode-desarrollo__item:first-child {\n  padding-top: 0;\n}\n.onode-desarrollo__item:focus-visible {\n  outline: 2px solid #335673;\n  outline-offset: 4px;\n}\n.onode-desarrollo__item.is-active {\n  border-bottom-color: #335673;\n}\n\n\/* Cabecera: t\u00edtulo a la izquierda, flecha a la derecha *\/\n.onode-desarrollo__head {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: 24px;\n}\n\/* T\u00edtulo de cada pesta\u00f1a *\/\n.onode-desarrollo__item h3 {\n  margin: 0;\n  font-size: 32px;\n  font-weight: 700;\n  line-height: 1.15;\n  color: #a3b7c4;\n  transition: color .25s ease;\n}\n.onode-desarrollo__item.is-active h3 {\n  color: #335673;\n}\n\n\/* Flecha *\/\n.onode-desarrollo__icon {\n  display: block;\n  flex: 0 0 auto;\n  width: 14px;\n  height: 14px;\n  margin-right: 6px;\n  border-right: 2px solid #93a9b8;\n  border-bottom: 2px solid #93a9b8;\n  transform: rotate(45deg);\n  transition: transform .3s ease, border-color .3s ease;\n}\n.onode-desarrollo__item.is-active .onode-desarrollo__icon {\n  transform: rotate(-135deg);\n  border-color: #335673;\n}\n\n\/* Descripci\u00f3n desplegable *\/\n.onode-desarrollo__desc {\n  display: grid;\n  grid-template-rows: 0fr;\n  transition: grid-template-rows .35s ease;\n}\n.onode-desarrollo__item.is-active .onode-desarrollo__desc {\n  grid-template-rows: 1fr;\n}\n.onode-desarrollo__desc-inner {\n  overflow: hidden;\n  min-height: 0;\n}\n.onode-desarrollo__desc-text {\n  padding-top: 16px;\n  color: #335673;\n  font-size: 20px;\n  line-height: 1.5;\n  font-weight: 300;\n}\n.onode-desarrollo__desc-text p {\n  margin: 0 0 14px;\n  padding: 0;\n  color: inherit;\n  font-size: inherit;\n  line-height: inherit;\n  font-weight: inherit;\n  font-family: inherit;\n}\n.onode-desarrollo__desc-text p:last-child {\n  margin-bottom: 0;\n}\n\n\/* Descripciones con texto m\u00e1s peque\u00f1o (las indicadas en $descripciones_pequenas) *\/\n.onode-desarrollo__desc-text.is-small {\n  font-size: 16px;\n}\n.onode-desarrollo__desc-text.is-small p {\n  margin-bottom: 10px;\n}\n.onode-desarrollo__desc-text.is-small p:last-child {\n  margin-bottom: 0;\n}\n\n\/* ---------- M\u00d3VIL ---------- *\/\n@media (max-width: 900px) {\n  .onode-desarrollo {\n    grid-template-columns: 1fr;\n    gap: 0;\n    padding: 0;\n  }\n\n  \/* Se oculta la foto *\/\n  .onode-desarrollo__media {\n    display: none;\n  }\n\n  .onode-desarrollo__list {\n    margin-top: 0 !important;\n  }\n  .onode-desarrollo__item {\n    padding: 22px 0;\n  }\n  .onode-desarrollo__item:first-child {\n    padding-top: 22px;\n  }\n  .onode-desarrollo__head {\n    gap: 16px;\n  }\n  .onode-desarrollo__item h3 {\n    font-size: 24px;\n  }\n  .onode-desarrollo__icon {\n    width: 12px;\n    height: 12px;\n    margin-right: 4px;\n  }\n  .onode-desarrollo__desc-text {\n    padding-top: 14px;\n    font-size: 17px;\n    line-height: 1.55;\n  }\n  .onode-desarrollo__desc-text.is-small {\n    font-size: 15px;\n  }\n}\n<\/style>\n\n<script>\n(function () {\n\n  \/\/ Retardo antes de abrir al pasar el rat\u00f3n (0 = al instante)\n  var HOVER_DELAY = 0;\n  \/\/ Pausa breve mientras se abre una pesta\u00f1a (evita el efecto rebote)\n  var ANIMATION_LOCK = 250;\n\n  \/\/ \u00bfDispositivo con rat\u00f3n? (en m\u00f3vil\/tablet se sigue abriendo al tocar)\n  function canHover() {\n    return window.matchMedia &&\n      window.matchMedia('(hover: hover) and (pointer: fine)').matches &&\n      window.innerWidth > 900;\n  }\n\n  function initDesarrollo(wrap) {\n    \/\/ Evita activar dos veces el mismo acorde\u00f3n\n    if (wrap.getAttribute(\"data-onode-init\") === \"1\") return;\n    wrap.setAttribute(\"data-onode-init\", \"1\");\n\n    var photos = wrap.querySelectorAll(\".onode-desa-photo\");\n    var items = wrap.querySelectorAll(\".onode-desarrollo__item\");\n    var list = wrap.querySelector(\".onode-desarrollo__list\");\n    var photoBox = wrap.querySelector(\".onode-desarrollo__photo\");\n    var inners = wrap.querySelectorAll(\".onode-desarrollo__desc-inner\");\n    var texts = wrap.querySelectorAll(\".onode-desarrollo__desc-text\");\n\n    var activeIndex = 0;\n    var hoveredIndex = -1;\n    var hoverTimer = null;\n    var lockUntil = 0;\n\n    photos.forEach(function (p) {\n      if (p.decode) {\n        p.decode().catch(function () {});\n      }\n    });\n\n    \/\/ Calcula la altura m\u00e1xima del acorde\u00f3n (con la descripci\u00f3n m\u00e1s larga abierta)\n    \/\/ y se la aplica a la foto para que no cambie de tama\u00f1o\n    function fixPhotoHeight() {\n      if (!photoBox || window.innerWidth <= 900) return;\n\n      \/\/ Altura del acorde\u00f3n sin ninguna descripci\u00f3n abierta\n      var openNow = 0;\n      inners.forEach(function (el) {\n        openNow += el.offsetHeight;\n      });\n      var closedHeight = list.offsetHeight - openNow;\n\n      \/\/ Descripci\u00f3n m\u00e1s alta\n      var maxDesc = 0;\n      texts.forEach(function (el) {\n        maxDesc = Math.max(maxDesc, el.offsetHeight);\n      });\n\n      photoBox.style.height = Math.ceil(closedHeight + maxDesc) + \"px\";\n    }\n\n    function setActive(index) {\n      if (index === activeIndex) return;\n      activeIndex = index;\n      lockUntil = Date.now() + ANIMATION_LOCK;\n\n      [items, photos].forEach(function (group) {\n        group.forEach(function (el) {\n          el.classList.toggle(\"is-active\", el.getAttribute(\"data-index\") === String(index));\n        });\n      });\n      items.forEach(function (el) {\n        el.setAttribute(\"aria-expanded\", el.getAttribute(\"data-index\") === String(index) ? \"true\" : \"false\");\n      });\n    }\n\n    \/\/ Abrir por hover: al instante, o en cuanto termine la pausa\n    \/\/ si el rat\u00f3n sigue encima de esa pesta\u00f1a\n    function requestHover(index) {\n      clearTimeout(hoverTimer);\n      var wait = Math.max(HOVER_DELAY, lockUntil - Date.now(), 0);\n\n      if (wait === 0) {\n        setActive(index);\n        return;\n      }\n      hoverTimer = setTimeout(function () {\n        if (hoveredIndex === index) setActive(index);\n      }, wait);\n    }\n\n    items.forEach(function (item) {\n      var index = parseInt(item.getAttribute(\"data-index\"), 10);\n\n      \/\/ Clic (y toque en m\u00f3vil)\n      item.addEventListener(\"click\", function () {\n        clearTimeout(hoverTimer);\n        setActive(index);\n      });\n\n      \/\/ Teclado\n      item.addEventListener(\"keydown\", function (e) {\n        if (e.key === \"Enter\" || e.key === \" \") {\n          e.preventDefault();\n          setActive(index);\n        }\n      });\n\n      \/\/ Pasar el rat\u00f3n por encima (solo ordenador con rat\u00f3n)\n      \/\/ \"mousemove\": solo reacciona cuando el rat\u00f3n se mueve de verdad,\n      \/\/ no cuando la pesta\u00f1a se desplaza sola por debajo al abrirse otra.\n      item.addEventListener(\"mousemove\", function () {\n        if (!canHover()) return;\n        hoveredIndex = index;\n        if (index !== activeIndex) requestHover(index);\n      });\n\n      item.addEventListener(\"mouseleave\", function () {\n        if (hoveredIndex === index) hoveredIndex = -1;\n        clearTimeout(hoverTimer);\n      });\n    });\n\n    \/\/ Recalcular al cargar, al cargar la fuente y al cambiar el tama\u00f1o de la ventana\n    fixPhotoHeight();\n    if (document.fonts && document.fonts.ready) {\n      document.fonts.ready.then(fixPhotoHeight);\n    }\n    window.addEventListener(\"load\", fixPhotoHeight);\n    var resizeTimer;\n    window.addEventListener(\"resize\", function () {\n      clearTimeout(resizeTimer);\n      resizeTimer = setTimeout(fixPhotoHeight, 150);\n    });\n  }\n\n  function initAll() {\n    document.querySelectorAll(\".onode-desarrollo\").forEach(initDesarrollo);\n  }\n\n  \/\/ Espera a que la p\u00e1gina est\u00e9 cargada (por si un plugin mueve el script)\n  if (document.readyState === \"loading\") {\n    document.addEventListener(\"DOMContentLoaded\", initAll);\n  } else {\n    initAll();\n  }\n})();\n<\/script>\n\t<\/div><\/div>\n<\/div>\n<\/div>\n<\/div>\n\n<div class=\"et_pb_section_4 et_pb_section et_section_regular et_flex_section\">\n<div class=\"et_pb_row_4 et_pb_row et_flex_row\">\n<div class=\"et_pb_column_4 et_pb_column et-last-child et_flex_column et_pb_css_mix_blend_mode_passthrough et_flex_column_24_24 et_flex_column_24_24_tablet et_flex_column_24_24_phone\">\n<div class=\"et_pb_text_5 et_pb_text et_pb_bg_layout_light et_pb_module et_flex_module\"><div class=\"et_pb_text_inner\"><p><span>How we work<\/span><\/p>\n<\/div><\/div>\n<\/div>\n<\/div>\n\n<div class=\"et_pb_row_5 et_pb_row et_flex_row\">\n<div class=\"et_pb_column_5 et_pb_column et_flex_column et_pb_css_mix_blend_mode_passthrough et_flex_column_12_24 et_flex_column_12_24_tablet et_flex_column_24_24_phone\">\n<div class=\"et_pb_row_6 et_pb_row et_pb_row_nested et_flex_row\">\n<div class=\"et_pb_column_6 et_pb_column et_flex_column et_pb_css_mix_blend_mode_passthrough et_flex_column_6_24 et_flex_column_6_24_tablet et_flex_column_24_24_phone\">\n<div class=\"et_pb_image_0 et_pb_image et_pb_module et_flex_module\"><span class=\"et_pb_image_wrap\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/onode.es\/wp-content\/uploads\/2026\/09\/texto-sello.png\" title=\"texto sello\" width=\"512\" height=\"512\" srcset=\"https:\/\/onode.es\/wp-content\/uploads\/2026\/09\/texto-sello.png 512w, https:\/\/onode.es\/wp-content\/uploads\/2026\/09\/texto-sello-480x480.png 480w\" sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 512px, 100vw\" class=\"wp-image-1561\" \/><\/span><\/div>\n<\/div>\n\n<div class=\"et_pb_column_7 et_pb_column et-last-child et_flex_column et_pb_css_mix_blend_mode_passthrough et_flex_column_24_24 et_flex_column_24_24_tablet et_flex_column_24_24_phone\">\n<div class=\"et_pb_text_6 et_pb_text et_pb_bg_layout_light et_pb_module et_flex_module\"><div class=\"et_pb_text_inner\"><p><span>1. <strong>Listening and conceptualization<\/strong>: we thoroughly analyze the specific operational need alongside the requesting team or department.<\/span><\/p>\n<\/div><\/div>\n<\/div>\n<\/div>\n<\/div>\n\n<div class=\"et_pb_column_8 et_pb_column et-last-child et_flex_column et_pb_css_mix_blend_mode_passthrough et_flex_column_12_24 et_flex_column_12_24_tablet et_flex_column_24_24_phone\">\n<div class=\"et_pb_row_7 et_pb_row et_pb_row_nested et_flex_row\">\n<div class=\"et_pb_column_9 et_pb_column et_flex_column et_pb_css_mix_blend_mode_passthrough et_flex_column_6_24 et_flex_column_6_24_tablet et_flex_column_24_24_phone\">\n<div class=\"et_pb_image_1 et_pb_image et_pb_module et_flex_module\"><span class=\"et_pb_image_wrap\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/onode.es\/wp-content\/uploads\/2026\/09\/lapiz.png\" title=\"lapiz\" width=\"512\" height=\"512\" srcset=\"https:\/\/onode.es\/wp-content\/uploads\/2026\/09\/lapiz.png 512w, https:\/\/onode.es\/wp-content\/uploads\/2026\/09\/lapiz-480x480.png 480w\" sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 512px, 100vw\" class=\"wp-image-1563\" \/><\/span><\/div>\n<\/div>\n\n<div class=\"et_pb_column_10 et_pb_column et-last-child et_flex_column et_pb_css_mix_blend_mode_passthrough et_flex_column_24_24 et_flex_column_24_24_tablet et_flex_column_24_24_phone\">\n<div class=\"et_pb_text_7 et_pb_text et_pb_bg_layout_light et_pb_module et_flex_module\"><div class=\"et_pb_text_inner\"><p><span>2. <strong>Solution Design<\/strong>: We define the most suitable technical architecture, workflows, and user experience.<\/span><\/p>\n<\/div><\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n\n<div class=\"et_pb_row_8 et_pb_row et_flex_row\">\n<div class=\"et_pb_column_11 et_pb_column et_flex_column et_pb_css_mix_blend_mode_passthrough et_flex_column_12_24 et_flex_column_12_24_tablet et_flex_column_24_24_phone\">\n<div class=\"et_pb_row_9 et_pb_row et_pb_row_nested et_flex_row\">\n<div class=\"et_pb_column_12 et_pb_column et_flex_column et_pb_css_mix_blend_mode_passthrough et_flex_column_6_24 et_flex_column_6_24_tablet et_flex_column_24_24_phone\">\n<div class=\"et_pb_image_2 et_pb_image et_pb_module et_flex_module\"><span class=\"et_pb_image_wrap\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/onode.es\/wp-content\/uploads\/2026\/09\/mazo.png\" title=\"mazo\" width=\"512\" height=\"512\" srcset=\"https:\/\/onode.es\/wp-content\/uploads\/2026\/09\/mazo.png 512w, https:\/\/onode.es\/wp-content\/uploads\/2026\/09\/mazo-480x480.png 480w\" sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 512px, 100vw\" class=\"wp-image-1560\" \/><\/span><\/div>\n<\/div>\n\n<div class=\"et_pb_column_13 et_pb_column et-last-child et_flex_column et_pb_css_mix_blend_mode_passthrough et_flex_column_24_24 et_flex_column_24_24_tablet et_flex_column_24_24_phone\">\n<div class=\"et_pb_text_8 et_pb_text et_pb_bg_layout_light et_pb_module et_flex_module\"><div class=\"et_pb_text_inner\"><p><span>3. <strong>Development and integration<\/strong>: we build custom software and connect it, when necessary, with existing systems and infrastructure.<\/span><\/p>\n<\/div><\/div>\n<\/div>\n<\/div>\n<\/div>\n\n<div class=\"et_pb_column_14 et_pb_column et-last-child et_flex_column et_pb_css_mix_blend_mode_passthrough et_flex_column_12_24 et_flex_column_12_24_tablet et_flex_column_24_24_phone\">\n<div class=\"et_pb_row_10 et_pb_row et_pb_row_nested et_flex_row\">\n<div class=\"et_pb_column_15 et_pb_column et_flex_column et_pb_css_mix_blend_mode_passthrough et_flex_column_6_24 et_flex_column_6_24_tablet et_flex_column_24_24_phone\">\n<div class=\"et_pb_image_3 et_pb_image et_pb_module et_flex_module\"><span class=\"et_pb_image_wrap\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/onode.es\/wp-content\/uploads\/2026\/09\/estadistica.png\" title=\"estad\u00edstica\" width=\"512\" height=\"512\" srcset=\"https:\/\/onode.es\/wp-content\/uploads\/2026\/09\/estadistica.png 512w, https:\/\/onode.es\/wp-content\/uploads\/2026\/09\/estadistica-480x480.png 480w\" sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 512px, 100vw\" class=\"wp-image-1587\" \/><\/span><\/div>\n<\/div>\n\n<div class=\"et_pb_column_16 et_pb_column et-last-child et_flex_column et_pb_css_mix_blend_mode_passthrough et_flex_column_24_24 et_flex_column_24_24_tablet et_flex_column_24_24_phone\">\n<div class=\"et_pb_text_9 et_pb_text et_pb_bg_layout_light et_pb_module et_flex_module\"><div class=\"et_pb_text_inner\"><p><span>4. <strong>Continuous support<\/strong>: we provide support for the implementation, training, and evolution of the solution once it is in production.<\/span><\/p>\n<\/div><\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n\n<div class=\"et_pb_section_5 et_pb_section et_section_regular et_flex_section\">\n<div class=\"et_pb_row_11 et_pb_row et_flex_row\">\n<div class=\"et_pb_column_17 et_pb_column et_flex_column et_pb_css_mix_blend_mode_passthrough et_flex_column_3_5 et_flex_column_3_5_tablet et_flex_column_24_24_phone\">\n<div class=\"et_pb_text_10 et_pb_text et_pb_bg_layout_light et_pb_module et_flex_module\"><div class=\"et_pb_text_inner\"><p>A multidisciplinary team<\/p>\n<\/div><\/div>\n\n<div class=\"et_pb_text_11 et_pb_text et_pb_bg_layout_light et_pb_module et_flex_module\"><div class=\"et_pb_text_inner\"><p><span>An expert team at your disposal<\/span><\/p>\n<\/div><\/div>\n\n<div class=\"et_pb_text_12 et_pb_text et_pb_bg_layout_light et_pb_module et_flex_module\"><div class=\"et_pb_text_inner\"><p><span>The service is provided by a multidisciplinary team of specialists, including Data Protection Officers,<\/span><span> Compliance<\/span><span> <\/span><span>Officers<\/span><span>, and lawyers specializing in digital law and new technologies.<br \/><\/span><br \/><span>This combination of expertise allows us to offer rigorous, up-to-date advice tailored to the technical and legal realities of each organization.<\/span><\/p>\n<\/div><\/div>\n\n<div class=\"et_pb_module et_pb_button_module_wrapper et_pb_button_0_wrapper\"><a class=\"et_pb_button_0 et_pb_button et_pb_bg_layout_dark et_pb_module et_flex_module onode-btn-conoce\" href=\"https:\/\/onode.es\/en\/about-onode\/\">Meet us<\/a><\/div>\n<\/div>\n\n<div class=\"et_pb_column_18 et_pb_column et-last-child et_flex_column et_pb_css_mix_blend_mode_passthrough et_flex_column_2_5 et_flex_column_2_5_tablet et_flex_column_24_24_phone\">\n<div class=\"et_pb_image_4 et_pb_image et_pb_module et_flex_module\"><span class=\"et_pb_image_wrap\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/onode.es\/wp-content\/uploads\/2026\/07\/MARIA.jpg\" title=\"MARI\u0301A\" width=\"800\" height=\"960\" srcset=\"https:\/\/onode.es\/wp-content\/uploads\/2026\/07\/MARIA.jpg 800w, https:\/\/onode.es\/wp-content\/uploads\/2026\/07\/MARIA-480x576.jpg 480w\" sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 800px, 100vw\" class=\"wp-image-485\" \/><\/span><\/div>\n<\/div>\n<\/div>\n<\/div>\n\n<div class=\"et_pb_section_6 et_pb_section et_section_regular et_flex_section\">\n<div class=\"et_pb_row_12 et_pb_row et_flex_row\">\n<div class=\"et_pb_column_19 et_pb_column et-last-child et_flex_column et_pb_css_mix_blend_mode_passthrough et_flex_column_24_24 et_flex_column_24_24_tablet et_flex_column_24_24_phone\">\n<div class=\"et_pb_text_13 et_pb_text et_pb_bg_layout_light et_pb_module et_flex_module\"><div class=\"et_pb_text_inner\"><p><span>A service designed for what has no standard solution.<\/span><\/p>\n<\/div><\/div>\n\n<div class=\"et_pb_text_14 et_pb_text et_pb_bg_layout_light et_pb_module et_flex_module\"><div class=\"et_pb_text_inner\"><p><span>When a need doesn't fit into any predefined platform, Software on Demand is the way to build, from scratch or from existing systems, the exact technological solution your organization needs, powered by Artificial Intelligence.<\/span><\/p>\n<\/div><\/div>\n<\/div>\n<\/div>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":1242,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"footnotes":""},"class_list":["post-1257","page","type-page","status-publish","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/onode.es\/en\/wp-json\/wp\/v2\/pages\/1257","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/onode.es\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/onode.es\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/onode.es\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/onode.es\/en\/wp-json\/wp\/v2\/comments?post=1257"}],"version-history":[{"count":11,"href":"https:\/\/onode.es\/en\/wp-json\/wp\/v2\/pages\/1257\/revisions"}],"predecessor-version":[{"id":1703,"href":"https:\/\/onode.es\/en\/wp-json\/wp\/v2\/pages\/1257\/revisions\/1703"}],"up":[{"embeddable":true,"href":"https:\/\/onode.es\/en\/wp-json\/wp\/v2\/pages\/1242"}],"wp:attachment":[{"href":"https:\/\/onode.es\/en\/wp-json\/wp\/v2\/media?parent=1257"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}