{"id":258,"date":"2025-03-14T09:18:26","date_gmt":"2025-03-14T09:18:26","guid":{"rendered":"https:\/\/zabalimp.es\/?page_id=258"},"modified":"2026-04-24T09:41:08","modified_gmt":"2026-04-24T08:41:08","slug":"servicios","status":"publish","type":"page","link":"https:\/\/zabalimp.es\/eu\/servicios\/","title":{"rendered":"Zerbitzuak"},"content":{"rendered":"<div data-elementor-type=\"wp-page\" data-elementor-id=\"258\" class=\"elementor elementor-258\" data-elementor-post-type=\"page\">\n\t\t\t\t<a class=\"elementor-element elementor-element-6b71666 e-flex e-con-boxed e-con e-parent\" data-id=\"6b71666\" 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-2aa4c02 elementor-widget elementor-widget-html\" data-id=\"2aa4c02\" 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<div id=\"zb-services-public\" class=\"zb-services-public\"><\/div>\r\n\r\n<script>\r\n(function(){\r\n  const root = document.getElementById('zb-services-public');\r\n  if(!root) return;\r\n\r\n  function getCurrentLangPrefix() {\r\n    const lang = document.documentElement.lang || 'es';\r\n    return (lang === 'es' || lang.startsWith('es')) ? '' : `\/${lang.split('-')[0]}`;\r\n  }\r\n\r\n  function esc(s){\r\n    return String(s ?? '').replace(\/[&<>\"']\/g, m => ({\r\n      '&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'\r\n    }[m]));\r\n  }\r\n\r\n  \/\/ --- skeleton (\u0438\u043c\u0438\u0442\u0430\u0446\u0438\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438)\r\n  function renderSkeleton(n=4){\r\n    root.innerHTML = Array.from({length:n}).map(() => `\r\n      <article class=\"svc-card is-skeleton\">\r\n        <div class=\"svc-media\"><div class=\"sk sk-img\"><\/div><\/div>\r\n        <div class=\"svc-body\">\r\n          <div class=\"sk sk-title\"><\/div>\r\n          <div class=\"sk sk-line\"><\/div>\r\n          <div class=\"sk sk-line\"><\/div>\r\n          <div class=\"sk sk-line short\"><\/div>\r\n          <div class=\"svc-actions\"><div class=\"sk sk-btn\"><\/div><\/div>\r\n        <\/div>\r\n      <\/article>\r\n    `).join('');\r\n  }\r\n\r\n  \/\/ --- reveal text by sentences (\u043a\u0430\u043a \u201c\u043f\u043e \u0441\u0442\u0440\u043e\u043a\u0430\u043c\/\u0444\u0440\u0430\u0437\u0430\u043c\u201d)\r\n  function revealLines(el){\r\n    if(el.dataset.revealed === '1') return;\r\n    el.dataset.revealed = '1';\r\n\r\n    const text = el.dataset.full || '';\r\n    const chunks = text\r\n      .split(\/(?<=[.!?\u2026])\\s+\/)         \/\/ \u043f\u043e \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u043c\r\n      .map(s => s.trim())\r\n      .filter(Boolean);\r\n\r\n    el.innerHTML = chunks.map(s => `<span class=\"svc-line\">${esc(s)} <\/span>`).join('');\r\n\r\n    \/\/ \u043a\u0430\u0441\u043a\u0430\u0434\u043d\u0430\u044f \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0430 \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u044f\r\n    requestAnimationFrame(()=>{\r\n      el.querySelectorAll('.svc-line').forEach((line, i)=>{\r\n        line.style.transitionDelay = (i * 220) + 'ms';\r\n        line.classList.add('is-in');\r\n      });\r\n    });\r\n  }\r\n\r\n  function mountInteractions(){\r\n    \/\/ \u043a\u043b\u0438\u043a\u0438 -> hacer-pedido\r\n    root.querySelectorAll('.btn-solicitar-servicio').forEach(btn => {\r\n      btn.addEventListener('click', (e) => {\r\n        e.preventDefault();\r\n        const servicioId = btn.getAttribute('data-servicio-id');\r\n        const prefix = getCurrentLangPrefix();\r\n        window.location.href = `${prefix}\/hacer-pedido\/?servicio_id=${encodeURIComponent(servicioId)}`;\r\n      });\r\n    });\r\n\r\n    \/\/ \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0438 \u041f\u041e \u041c\u0415\u0420\u0415 \u041f\u0420\u041e\u041a\u0420\u0423\u0422\u041a\u0418 (\u043f\u043e\u0437\u0436\u0435 \u0438 \u043f\u043b\u0430\u0432\u043d\u0435\u0435)\r\n    const io = new IntersectionObserver((entries)=>{\r\n      entries.forEach(ent=>{\r\n        if(!ent.isIntersecting) return;\r\n\r\n        const card = ent.target;\r\n        if(card.dataset.shown === '1') return;\r\n        card.dataset.shown = '1';\r\n\r\n        card.classList.add('is-in');\r\n\r\n        const txt = card.querySelector('.svc-text');\r\n        if(txt) revealLines(txt);\r\n\r\n        \/\/ \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u043f\u0438\u0441\u0430\u0442\u044c\u0441\u044f \u0447\u0443\u0442\u044c \u043f\u043e\u0437\u0436\u0435, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0434\u0435\u0440\u0433\u0430\u0442\u044c \u043b\u0438\u0448\u043d\u0438\u0439 \u0440\u0430\u0437\r\n        setTimeout(()=> io.unobserve(card), 1500);\r\n      });\r\n    }, {\r\n      root: null,\r\n      rootMargin: '0px 0px -1% 0px',\r\n      threshold: 0.55\r\n    });\r\n\r\n    root.querySelectorAll('.svc-card:not(.is-skeleton)').forEach(card => io.observe(card));\r\n  }\r\n\r\n  async function loadServices(){\r\n    renderSkeleton(4);\r\n\r\n    try{\r\n      const r = await fetch('\/wp-json\/zabalimp\/v1\/services\/public?_ts=' + Date.now(), { cache:'no-store' });\r\n      const j = await r.json();\r\n      if(!j || !j.success) { root.innerHTML = '<p class=\"svc-err\">Error cargando servicios<\/p>'; return; }\r\n\r\n      root.innerHTML = j.data.map((s) => `\r\n        <article class=\"svc-card\">\r\n          <div class=\"svc-media\">\r\n            ${s.image_url\r\n              ? `<img decoding=\"async\" loading=\"lazy\" src=\"${esc(s.image_url)}\" alt=\"${esc(s.name)}\">`\r\n              : `<div class=\"svc-ph\"><\/div>`\r\n            }\r\n          <\/div>\r\n\r\n          <div class=\"svc-body\">\r\n            <h3 class=\"svc-title\">${esc(s.name)}<\/h3>\r\n            <div class=\"svc-text\" data-full=\"${esc(s.description || '')}\"><\/div>\r\n\r\n            <div class=\"svc-actions\">\r\n              <a href=\"#\" class=\"btn-solicitar-servicio\" data-servicio-id=\"${Number(s.id)}\">\r\n                Solicitar servicio\r\n              <\/a>\r\n            <\/div>\r\n          <\/div>\r\n        <\/article>\r\n      `).join('');\r\n\r\n      mountInteractions();\r\n    }catch(err){\r\n      root.innerHTML = '<p class=\"svc-err\">Error de conexi\u00f3n<\/p>';\r\n      console.error(err);\r\n    }\r\n  }\r\n\r\n  loadServices();\r\n})();\r\n<\/script>\r\n\r\n<style>\r\n\/* ===== Layout ===== *\/\r\n.zb-services-public{ display:grid; gap:22px; }\r\n\r\n.svc-card{\r\n  --shadow: 0 16px 40px rgba(0,0,0,.10);\r\n  display:grid;\r\n  grid-template-columns: 420px minmax(0, 1fr);\r\n  gap:18px;\r\n  padding:18px;\r\n  border-radius:18px;\r\n  background:#fff;\r\n  border:1px solid rgba(0,0,0,.08);\r\n  box-shadow: 0 1px 0 rgba(0,0,0,.02);\r\n  overflow:hidden;\r\n\r\n  opacity:0;\r\n  transform: translateY(16px);\r\n  transition:\r\n    opacity .85s cubic-bezier(.22,1,.36,1),\r\n    transform .85s cubic-bezier(.22,1,.36,1),\r\n    box-shadow .85s ease;\r\n}\r\n.svc-card.is-in{\r\n  opacity:1;\r\n  transform: translateY(0);\r\n  box-shadow: var(--shadow);\r\n}\r\n\r\n\/* ===== Media smoother reveal ===== *\/\r\n.svc-media{ position:relative; }\r\n.svc-media img,\r\n.svc-ph{\r\n  width:100%;\r\n  height:100%;\r\n  min-height:260px;\r\n  object-fit:cover;\r\n  border-radius:14px;\r\n  display:block;\r\n\r\n  transform: translateX(-48px) scale(1.05);\r\n  opacity:0;\r\n  filter: blur(10px);\r\n  transition:\r\n    transform 1.2s cubic-bezier(.22,1,.36,1),\r\n    opacity 1.2s ease,\r\n    filter 1.2s ease;\r\n}\r\n.svc-card.is-in .svc-media img,\r\n.svc-card.is-in .svc-ph{\r\n  transform: translateX(0) scale(1);\r\n  opacity:1;\r\n  filter: blur(0);\r\n}\r\n\r\n.svc-title{ margin:0 0 10px; font-size:26px; font-weight:900; }\r\n.svc-text{ line-height:1.55; color:rgba(0,0,0,.75); min-height: 5.2em; overflow:hidden; }\r\n.svc-actions{ margin-top:14px; display:flex; justify-content:flex-end; align-items:center; }\r\n\r\n\/* ===== Text reveal by \u201clines\/chunks\u201d ===== *\/\r\n.svc-line{\r\n  display:inline-block;\r\n  opacity:0;\r\n  transform: translateY(10px);\r\n  filter: blur(2px);\r\n  transition:\r\n    opacity .55s ease,\r\n    transform .55s ease,\r\n    filter .55s ease;\r\n}\r\n.svc-line.is-in{\r\n  opacity:1;\r\n  transform: translateY(0);\r\n  filter: blur(0);\r\n}\r\n\r\n\/* ===== 3D button ===== *\/\r\n.btn-solicitar-servicio{\r\n  position:relative;\r\n  display:inline-flex;\r\n  align-items:center;\r\n  justify-content:center;\r\n  padding:12px 18px;\r\n  border-radius:12px;\r\n  background: #f3d34c;\r\n  color:#111;\r\n  font-weight:900;\r\n  text-decoration:none;\r\n  transform: translateY(0);\r\n  box-shadow:\r\n    0 10px 0 rgba(0,0,0,.18),\r\n    0 18px 35px rgba(0,0,0,.18);\r\n  transition: transform .18s ease, box-shadow .18s ease, filter .18s ease;\r\n  outline: none;\r\n}\r\n.btn-solicitar-servicio::before{\r\n  content:\"\";\r\n  position:absolute;\r\n  inset:0;\r\n  border-radius:12px;\r\n  background: linear-gradient(120deg, rgba(255,255,255,.45), rgba(255,255,255,0) 55%);\r\n  opacity:0;\r\n  transition: opacity .18s ease;\r\n  pointer-events:none;\r\n}\r\n.btn-solicitar-servicio:hover{\r\n  transform: translateY(-2px);\r\n  box-shadow:\r\n    0 12px 0 rgba(0,0,0,.20),\r\n    0 22px 42px rgba(0,0,0,.22);\r\n  filter: saturate(1.05);\r\n}\r\n.btn-solicitar-servicio:hover::before{ opacity:.65; }\r\n.btn-solicitar-servicio:active{\r\n  transform: translateY(6px);\r\n  box-shadow:\r\n    0 4px 0 rgba(0,0,0,.20),\r\n    0 10px 22px rgba(0,0,0,.18);\r\n}\r\n.btn-solicitar-servicio:focus-visible{\r\n  box-shadow:\r\n    0 10px 0 rgba(0,0,0,.18),\r\n    0 18px 35px rgba(0,0,0,.18),\r\n    0 0 0 3px rgba(14,115,184,.25);\r\n}\r\n\r\n\/* ===== Skeleton shimmer ===== *\/\r\n.is-skeleton{\r\n  opacity:1 !important;\r\n  transform:none !important;\r\n  box-shadow: none !important;\r\n}\r\n.sk{\r\n  position:relative;\r\n  border-radius:12px;\r\n  background: rgba(0,0,0,.06);\r\n  overflow:hidden;\r\n}\r\n.sk::after{\r\n  content:\"\";\r\n  position:absolute;\r\n  inset:0;\r\n  transform: translateX(-100%);\r\n  background: linear-gradient(90deg, transparent, rgba(255,255,255,.55), transparent);\r\n  animation: sk 1.2s infinite;\r\n}\r\n@keyframes sk{ to { transform: translateX(100%); } }\r\n.sk-img{ height:260px; border-radius:14px; }\r\n.sk-title{ height:28px; width:60%; margin:6px 0 14px; }\r\n.sk-line{ height:14px; width:100%; margin:10px 0; }\r\n.sk-line.short{ width:78%; }\r\n.sk-btn{ height:42px; width:180px; border-radius:12px; }\r\n\r\n.svc-err{ padding:14px; background: rgba(185,14,46,.08); border:1px solid rgba(185,14,46,.18); border-radius:14px; }\r\n\r\n\/* ===== Responsive ===== *\/\r\n@media (max-width: 980px){\r\n  .svc-card{ grid-template-columns: 1fr; }\r\n  .svc-actions{ justify-content:flex-start; }\r\n  .svc-media img, .svc-ph, .sk-img{ min-height:220px; height:220px; }\r\n}\r\n<\/style>\r\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/a>\n\t\t\t\t<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-258","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/zabalimp.es\/eu\/wp-json\/wp\/v2\/pages\/258","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/zabalimp.es\/eu\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/zabalimp.es\/eu\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/zabalimp.es\/eu\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/zabalimp.es\/eu\/wp-json\/wp\/v2\/comments?post=258"}],"version-history":[{"count":193,"href":"https:\/\/zabalimp.es\/eu\/wp-json\/wp\/v2\/pages\/258\/revisions"}],"predecessor-version":[{"id":6233,"href":"https:\/\/zabalimp.es\/eu\/wp-json\/wp\/v2\/pages\/258\/revisions\/6233"}],"wp:attachment":[{"href":"https:\/\/zabalimp.es\/eu\/wp-json\/wp\/v2\/media?parent=258"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}