{"id":10532,"date":"2026-09-15T15:06:44","date_gmt":"2026-09-15T14:06:44","guid":{"rendered":"https:\/\/letsrideportugal.com\/?page_id=10532"},"modified":"2026-09-18T18:06:54","modified_gmt":"2026-09-18T17:06:54","slug":"fechas-de-rutas","status":"publish","type":"page","link":"https:\/\/letsrideportugal.com\/es\/fechas-de-rutas\/","title":{"rendered":"Fechas de rutas"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"10532\" class=\"elementor elementor-10532 elementor-10522\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-ab15c000 e-con-full e-flex e-con e-parent\" data-id=\"ab15c000\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-ab15c001 elementor-widget elementor-widget-shortcode\" data-id=\"ab15c001\" data-element_type=\"widget\" data-widget_type=\"shortcode.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\"><style>.lrp-availability{--lrp-ink:#f6f2e8;--lrp-muted:#c7c6b8;--lrp-orange:#fa671c;--lrp-gold:#ffbd66;--lrp-line:#393d2d;box-sizing:border-box;color:var(--lrp-ink);background:#171813;font-family:inherit;padding:64px 24px;isolation:isolate}.lrp-availability *{box-sizing:border-box}.lrp-av-inner{max-width:1140px;margin:auto}.lrp-av-eyebrow{color:var(--lrp-gold);letter-spacing:.12em;font-size:13px;font-weight:700;margin:0 0 16px}.lrp-availability h1,.lrp-availability h2,.lrp-availability h3{color:var(--lrp-ink);text-transform:none;margin:0;line-height:1.15}.lrp-availability h1,.lrp-availability h2.lrp-av-title{font-size:clamp(34px,4.5vw,58px);max-width:850px}.lrp-av-intro{max-width:760px;color:var(--lrp-muted);font-size:18px;line-height:1.7;margin:20px 0 36px}.lrp-av-layout{display:grid;grid-template-columns:minmax(0,.9fr) minmax(0,1.25fr);gap:28px;align-items:start}.lrp-av-monthbox{border:1px solid var(--lrp-line);background:#20221b;padding:24px;border-radius:20px;position:sticky;top:24px}.lrp-av-toolbar{display:flex;align-items:center;gap:10px;margin-bottom:24px}.lrp-availability button,.lrp-availability select{font:inherit;cursor:pointer}.lrp-av-toolbar select{width:100%;min-width:0;background:#171813;border:1px solid var(--lrp-line);color:var(--lrp-ink);padding:12px;border-radius:10px;font-weight:700}.lrp-av-arrow{display:grid;place-items:center;background:#171813;color:var(--lrp-orange);border:1px solid var(--lrp-line);border-radius:12px;flex:0 0 44px;width:44px;height:44px;padding:0;line-height:1}.lrp-av-arrow svg{width:20px;height:20px;stroke:currentColor;fill:none;stroke-width:2.5}.lrp-av-arrow:disabled{opacity:.35;cursor:default}.lrp-av-grid{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:5px}.lrp-av-weekday{text-align:center;color:var(--lrp-muted);font-size:12px;margin-bottom:10px}.lrp-av-date{aspect-ratio:1;border:1px solid transparent;border-radius:9px;background:transparent;color:var(--lrp-muted);padding:0;min-height:38px;display:grid;place-items:center;font-size:14px}.lrp-av-date.has-tour{background:#392d1d;color:var(--lrp-gold);border-color:#66502f;font-weight:700}.lrp-av-date.is-selected{background:var(--lrp-orange);color:#14150f;border-color:var(--lrp-orange)}.lrp-av-date.is-today{outline:1px solid var(--lrp-muted);outline-offset:-4px}.lrp-av-legend{display:flex;align-items:center;gap:9px;font-size:13px;color:var(--lrp-muted);margin:18px 0}.lrp-av-dot{width:9px;height:9px;display:inline-block;border-radius:50%;background:var(--lrp-orange)}.lrp-av-reset{background:none;color:var(--lrp-gold);padding:6px 0;border:0;text-decoration:underline;font-size:13px}.lrp-av-list{display:grid;gap:16px;min-width:0}.lrp-av-card{border:1px solid var(--lrp-line);border-radius:20px;background:#20221b;padding:26px;min-width:0}.lrp-av-card h2,.lrp-av-card h3{font-size:26px;margin:12px 0}.lrp-av-date-range{color:var(--lrp-gold);font-size:14px;font-weight:700;letter-spacing:.015em}.lrp-av-tags{display:flex;gap:8px;flex-wrap:wrap;margin:12px 0 18px}.lrp-av-tag{font-size:12px;line-height:1.5;color:var(--lrp-muted);border:1px solid var(--lrp-line);border-radius:6px;padding:4px 8px}.lrp-av-capacity{display:flex;justify-content:space-between;gap:14px;align-items:baseline;margin:14px 0;padding-top:14px;border-top:1px solid var(--lrp-line);font-size:15px;line-height:1.4}.lrp-av-capacity strong{color:var(--lrp-gold);text-align:right}.lrp-av-actions{display:flex;gap:14px;align-items:center;flex-wrap:wrap;margin-top:20px}.lrp-av-cta{display:inline-flex;align-items:center;justify-content:center;background:var(--lrp-orange);color:#14150f!important;border:1px solid var(--lrp-orange);border-radius:10px;padding:12px 18px;min-height:46px;font-weight:700;font-size:14px;text-decoration:none!important;line-height:1.4}.lrp-av-cta:hover{background:var(--lrp-gold);border-color:var(--lrp-gold)}.lrp-av-secondary{color:var(--lrp-gold)!important;font-size:14px;text-underline-offset:4px}.lrp-av-empty{padding:26px;border:1px dashed var(--lrp-line);border-radius:20px;line-height:1.7;color:var(--lrp-muted)}.lrp-av-notes{margin-top:30px;border-top:1px solid var(--lrp-line);padding-top:24px;font-size:14px;line-height:1.7;color:var(--lrp-muted)}.lrp-av-notes p{margin:0 0 12px}.lrp-av-status{font-size:12px;color:var(--lrp-muted);margin:20px 0 0}.lrp-av-banner{margin:16px 0;color:var(--lrp-gold);font-size:14px}.lrp-availability :focus-visible{outline:3px solid var(--lrp-gold);outline-offset:4px}.lrp-availability [hidden]{display:none!important}.lrp-av-compact .lrp-av-layout{display:block}.lrp-av-compact .lrp-av-list{grid-template-columns:repeat(3,minmax(0,1fr))}.lrp-av-compact .lrp-av-card{padding:22px}.lrp-av-compact .lrp-av-capacity{flex-direction:column;gap:6px}.lrp-av-compact .lrp-av-more{margin-top:26px}.lrp-av-compact .lrp-av-intro{margin-bottom:26px}@media(max-width:850px){.lrp-av-layout{grid-template-columns:1fr}.lrp-av-monthbox{position:static;max-width:520px;width:100%}.lrp-av-compact .lrp-av-list{grid-template-columns:1fr}.lrp-av-compact .lrp-av-capacity{flex-direction:row}}@media(max-width:480px){.lrp-availability{padding:40px 16px}.lrp-av-intro{font-size:16px;line-height:1.6}.lrp-av-monthbox{padding:16px}.lrp-av-card{padding:20px}.lrp-av-card h2,.lrp-av-card h3{font-size:24px}.lrp-av-grid{gap:3px}.lrp-av-date{min-height:36px}.lrp-av-capacity{font-size:14px}.lrp-av-actions{align-items:stretch;flex-direction:column}.lrp-av-secondary{padding:6px 0}.lrp-av-toolbar{gap:6px}}\r\n.lrp-availability .lrp-av-intro{margin-bottom:20px}.lrp-av-intro-action{margin:0 0 34px}.lrp-availability button.lrp-av-secondary{border:0;background:transparent;padding:8px 0;text-align:left;text-decoration:underline;line-height:1.5}.lrp-av-date:disabled{opacity:.35;cursor:default}.lrp-av-dialog{color:var(--lrp-ink);background:#20221b;border:1px solid var(--lrp-line);border-radius:20px;padding:30px;width:min(480px,calc(100vw - 32px));max-height:calc(100dvh - 32px);overflow:auto;box-shadow:0 24px 80px #0008;font:inherit}.lrp-av-dialog::backdrop{background:#000b}.lrp-av-dialog h2{font-size:28px;margin:0 0 24px}.lrp-av-request-form{display:grid;gap:20px}.lrp-av-field{display:grid;gap:8px;font-size:15px;line-height:1.5;color:var(--lrp-ink)}.lrp-av-field input,.lrp-av-field select{width:100%;min-width:0;min-height:48px;margin:0;padding:12px;border-radius:9px;border:1px solid #626657;background:#171813;color:var(--lrp-ink);font:inherit;line-height:1.5;color-scheme:dark}.lrp-av-request-hint{color:var(--lrp-muted);font-size:14px;line-height:1.6;margin:0}.lrp-av-request-form .lrp-av-actions{margin-top:0}.lrp-av-request-form .lrp-av-actions button{cursor:pointer}.lrp-av-dialog :focus-visible{outline:3px solid var(--lrp-gold);outline-offset:3px}@media(max-width:480px){.lrp-av-dialog{padding:24px 20px}.lrp-av-dialog h2{font-size:25px}.lrp-av-dialog .lrp-av-secondary{text-align:center!important}.lrp-av-field input,.lrp-av-field select{font-size:16px}}\r\n\r\n.lrp-availability .lrp-av-cta{font-weight:700}\r\n.lrp-av-booked{background:#1d1f1a}.lrp-av-booked-tag{color:#f0b9ac;border-color:#775247;background:#352724;font-weight:700}.lrp-av-date.has-full-tour{background:#352724;border-color:#775247;color:#f0b9ac}.lrp-av-date.has-full-tour.is-selected{outline:2px solid #f0b9ac;outline-offset:1px}.lrp-av-legend{flex-wrap:wrap;column-gap:18px;row-gap:8px}.lrp-av-legend-item{display:inline-flex;align-items:center;gap:7px}.lrp-av-dot-full{background:#c78c7b}\r\n\r\n.lrp-av-dot-past{background:#a4a695}.lrp-av-date.has-past-tour{background:#2b3026;border-color:#626854;color:#eeeee5}\r\n.lrp-av-day-buttons{display:flex;flex-wrap:wrap;gap:8px;margin:16px 0}.lrp-availability .lrp-av-day-option{border:1px solid #66502f;border-radius:9px;background:#392d1d;color:var(--lrp-gold);padding:10px 12px;min-height:44px;line-height:1.4;font-size:14px}.lrp-availability .lrp-av-day-option.is-full{background:#352724;border-color:#775247;color:#f0b9ac}.lrp-availability .lrp-av-day-option.is-selected{outline:2px solid var(--lrp-gold);outline-offset:2px}.lrp-av-selection-actions{display:flex;flex-wrap:wrap;gap:16px;margin:12px 0}.lrp-av-selected-period{color:var(--lrp-ink);font-size:14px;margin:16px 0 8px}.lrp-availability .lrp-av-whole[aria-pressed=\"true\"]{font-weight:700}.lrp-av-selection{overflow-wrap:anywhere}\r\n<\/style><section class=\"lrp-availability\" lang=\"es-ES\"><div class=\"lrp-av-inner\"><p class=\"lrp-av-eyebrow\">FECHAS DE RUTAS \u00b7 ALGARVE, PORTUGAL<\/p><h1 class=\"lrp-av-title\">\u00danete a un grupo. O forma el tuyo.<\/h1><p class=\"lrp-av-intro\">Estas son nuestras rutas previstas. \u00bfPrefieres otras fechas? Solicita una nueva ruta con 3 o m\u00e1s pilotos. \u00bfSois dos? Escr\u00edbenos con bastante antelaci\u00f3n.<\/p><p class=\"lrp-av-intro-action\"><a class=\"lrp-av-cta lrp-av-custom-trigger\" href=\"https:\/\/letsrideportugal.com\/es\/contacto\/\">Solicitar tus fechas<\/a><\/p><p class=\"lrp-av-banner\" role=\"status\">Comprobando disponibilidad\u2026<\/p><div class=\"lrp-av-layout\"><div class=\"lrp-av-monthbox\" aria-label=\"Calendario de rutas\"><\/div><div class=\"lrp-av-list\" aria-live=\"polite\"><article class=\"lrp-av-card\"><div class=\"lrp-av-date-range\">2026-11-04 \u2013 2026-11-07<\/div><h2>Ruta de enduro de 4 d\u00edas<\/h2><p>Selecciona un d\u00eda de ruta para ver las plazas disponibles.<\/p><\/article><article class=\"lrp-av-card\"><div class=\"lrp-av-date-range\">2026-11-19 \u2013 2026-11-19<\/div><h2>Ruta de enduro de 1 d\u00edas<\/h2><p>Selecciona un d\u00eda de ruta para ver las plazas disponibles.<\/p><\/article><article class=\"lrp-av-card\"><div class=\"lrp-av-date-range\">2026-11-23 \u2013 2026-11-23<\/div><h2>Ruta de enduro de 1 d\u00edas<\/h2><p>Selecciona un d\u00eda de ruta para ver las plazas disponibles.<\/p><\/article><article class=\"lrp-av-card\"><div class=\"lrp-av-date-range\">2026-12-21 \u2013 2026-12-21<\/div><h2>Ruta de enduro de 1 d\u00edas<\/h2><p>Selecciona un d\u00eda de ruta para ver las plazas disponibles.<\/p><\/article><article class=\"lrp-av-card\"><div class=\"lrp-av-date-range\">2027-01-02 \u2013 2027-01-02<\/div><h2>Ruta de enduro de 1 d\u00edas<\/h2><p>Selecciona un d\u00eda de ruta para ver las plazas disponibles.<\/p><\/article><article class=\"lrp-av-card\"><div class=\"lrp-av-date-range\">2027-03-19 \u2013 2027-03-19<\/div><h2>Ruta de enduro de 1 d\u00edas<\/h2><p>Selecciona un d\u00eda de ruta para ver las plazas disponibles.<\/p><\/article><article class=\"lrp-av-card\"><div class=\"lrp-av-date-range\">2027-03-23 \u2013 2027-03-25<\/div><h2>Ruta de enduro de 3 d\u00edas<\/h2><p>Selecciona un d\u00eda de ruta para ver las plazas disponibles.<\/p><\/article><article class=\"lrp-av-card\"><div class=\"lrp-av-date-range\">2027-04-07 \u2013 2027-04-09<\/div><h2>Ruta de enduro de 3 d\u00edas<\/h2><p>Selecciona un d\u00eda de ruta para ver las plazas disponibles.<\/p><\/article><article class=\"lrp-av-card\"><div class=\"lrp-av-date-range\">2027-04-17 \u2013 2027-04-19<\/div><h2>Ruta de enduro de 3 d\u00edas<\/h2><p>Selecciona un d\u00eda de ruta para ver las plazas disponibles.<\/p><\/article><article class=\"lrp-av-card\"><div class=\"lrp-av-date-range\">2027-06-01 \u2013 2027-06-03<\/div><h2>Ruta de enduro de 3 d\u00edas<\/h2><p>Selecciona un d\u00eda de ruta para ver las plazas disponibles.<\/p><\/article><\/div><\/div><noscript><p>Cons\u00faltanos directamente las plazas disponibles. <a href=\"https:\/\/letsrideportugal.com\/es\/contacto\/\">Solicitar tus fechas<\/a><\/p><\/noscript><div class=\"lrp-av-notes\"><p>Nuestra casa: 3 habitaciones dobles, normalmente 6 hu\u00e9spedes. Los participantes de un solo d\u00eda no ocupan plazas de alojamiento.<\/p><p>Confirmamos personalmente la disponibilidad antes de reservar. Revisamos contigo el tama\u00f1o del grupo, el nivel y la moto. Los d\u00edas sin marcar no garantizan disponibilidad.<\/p><\/div><p class=\"lrp-av-status\"><\/p><script type=\"application\/json\" class=\"lrp-av-config\">{\"lang\":\"es\",\"compact\":false,\"strings\":{\"locale\":\"es-ES\",\"title\":\"\\u00danete a un grupo. O forma el tuyo.\",\"eyebrow\":\"FECHAS DE RUTAS \\u00b7 ALGARVE, PORTUGAL\",\"intro\":\"Estas son nuestras rutas previstas. \\u00bfPrefieres otras fechas? Solicita una nueva ruta con 3 o m\\u00e1s pilotos. \\u00bfSois dos? Escr\\u00edbenos con bastante antelaci\\u00f3n.\",\"month\":\"Elegir mes\",\"previous\":\"Mes anterior\",\"next\":\"Mes siguiente\",\"all\":\"Todas las fechas del mes\",\"planned\":\"Ruta prevista\",\"provisional\":\"Fechas provisionales\",\"request\":\"Bajo consulta\",\"tour\":\"Ruta de enduro de {n} d\\u00edas\",\"single\":\"Ruta de enduro de un d\\u00eda\",\"half\":\"\\u00daltimo d\\u00eda de ruta: medio d\\u00eda\",\"stay\":\"Con alojamiento\",\"day\":\"Rodar un d\\u00eda\",\"spaces\":\"{n} plazas\",\"space\":\"1 plaza\",\"inquire\":\"Consultar esta ruta\",\"dayInquire\":\"Consultar un d\\u00eda de ruta\",\"empty\":\"Todav\\u00eda no hay un grupo previsto para estas fechas. Forma uno con 3 o m\\u00e1s pilotos, o consulta con antelaci\\u00f3n si sois dos.\",\"custom\":\"Solicitar tus fechas\",\"note\":\"Confirmamos personalmente la disponibilidad antes de reservar. Revisamos contigo el tama\\u00f1o del grupo, el nivel y la moto. Los d\\u00edas sin marcar no garantizan disponibilidad.\",\"house\":\"Nuestra casa: 3 habitaciones dobles, normalmente 6 hu\\u00e9spedes. Los participantes de un solo d\\u00eda no ocupan plazas de alojamiento.\",\"stale\":\"Cons\\u00faltanos la disponibilidad actual.\",\"updated\":\"Calendario actualizado\",\"loading\":\"Comprobando disponibilidad\\u2026\",\"level\":\"Nivel\",\"beginner\":\"Principiante\",\"mixed\":\"Niveles variados\",\"experienced\":\"Experimentado\",\"calendar\":\"Calendario de rutas\",\"upcoming\":\"\\u00danete a un grupo. O forma el tuyo.\",\"viewAll\":\"Ver todas las fechas\",\"date\":\"Fecha\",\"close\":\"Borrar selecci\\u00f3n del d\\u00eda\",\"inquiryText\":\"Me interesa la ruta de {n} d\\u00edas del {start} al {end}.\",\"dayText\":\"Me gustar\\u00eda unirme un d\\u00eda a la ruta del {start} al {end}.\",\"daySelectedText\":\"Me gustar\\u00eda participar en la ruta del {start}.\",\"choose\":\"Seleccionar {date}\",\"nojs\":\"Cons\\u00faltanos directamente las plazas disponibles.\",\"dayTitle\":\"\\u00bfQu\\u00e9 d\\u00eda quieres rodar?\",\"daySelect\":\"D\\u00eda de ruta\",\"dayPlaceholder\":\"Elige un d\\u00eda\",\"continue\":\"Continuar con la consulta\",\"cancel\":\"Cancelar\",\"startDate\":\"Fecha de inicio deseada\",\"riders\":\"N\\u00famero de pilotos\",\"customMessage\":\"Quisiera solicitar una nueva ruta a partir del {start} para {riders} pilotos.\",\"soloHint\":\"\\u00bfVienes solo? Lo mejor suele ser unirte a un grupo existente.\",\"twoHint\":\"\\u00bfSois dos? Escribidnos con bastante antelaci\\u00f3n para que podamos formar un grupo.\",\"requestHint\":\"Te confirmaremos personalmente las fechas y la disponibilidad.\",\"fullyBooked\":\"Completo\",\"dateFullyBooked\":\"Esta fecha est\\u00e1 completa. Elige otra fecha.\",\"availabilityChanged\":\"La disponibilidad ha cambiado. Elige otro d\\u00eda de ruta.\",\"pastRides\":\"Rutas anteriores\",\"pastTour\":\"Ruta anterior\",\"readStory\":\"Leer la historia de la ruta\",\"noPast\":\"No hay rutas anteriores registradas para estas fechas.\",\"viewLabel\":\"Vista de rutas\",\"selectDayAvailability\":\"Selecciona un d\\u00eda de ruta para ver las plazas disponibles.\",\"selectTour\":\"Seleccionar toda la ruta\",\"clearSelection\":\"Borrar selecci\\u00f3n\",\"selectedPeriod\":\"Selecci\\u00f3n: {dates}\"},\"contact\":\"https:\\\/\\\/letsrideportugal.com\\\/es\\\/contacto\\\/\",\"endpoint\":\"https:\\\/\\\/letsrideportugal.com\\\/es\\\/wp-json\\\/lrp\\\/v1\\\/availability\",\"initial\":{\"fresh\":false,\"updated\":1793937746,\"tours\":[{\"id\":\"0f15ee909ce5a022\",\"start\":\"2025-09-26\",\"end\":\"2025-09-28\",\"days\":3,\"half_last\":false,\"level\":null,\"status\":\"past\",\"places\":null,\"beds\":null,\"day_places\":[],\"fully_booked\":false,\"story\":null},{\"id\":\"26e3f84a21f3a06c\",\"start\":\"2025-11-07\",\"end\":\"2025-11-09\",\"days\":3,\"half_last\":false,\"level\":null,\"status\":\"past\",\"places\":null,\"beds\":null,\"day_places\":[],\"fully_booked\":false,\"story\":null},{\"id\":\"1de3cec628323ab5\",\"start\":\"2025-11-13\",\"end\":\"2025-11-14\",\"days\":2,\"half_last\":false,\"level\":null,\"status\":\"past\",\"places\":null,\"beds\":null,\"day_places\":[],\"fully_booked\":false,\"story\":null},{\"id\":\"777a9d990d59f090\",\"start\":\"2025-11-22\",\"end\":\"2025-11-23\",\"days\":2,\"half_last\":false,\"level\":null,\"status\":\"past\",\"places\":null,\"beds\":null,\"day_places\":[],\"fully_booked\":false,\"story\":null},{\"id\":\"6afba9d4d5552af3\",\"start\":\"2025-12-28\",\"end\":\"2025-12-28\",\"days\":1,\"half_last\":false,\"level\":null,\"status\":\"past\",\"places\":null,\"beds\":null,\"day_places\":[],\"fully_booked\":false,\"story\":null},{\"id\":\"fe382f30290eaf26\",\"start\":\"2026-01-24\",\"end\":\"2026-01-24\",\"days\":1,\"half_last\":false,\"level\":null,\"status\":\"past\",\"places\":null,\"beds\":null,\"day_places\":[],\"fully_booked\":false,\"story\":null},{\"id\":\"7d4863457d352fff\",\"start\":\"2026-03-09\",\"end\":\"2026-03-10\",\"days\":2,\"half_last\":false,\"level\":null,\"status\":\"past\",\"places\":null,\"beds\":null,\"day_places\":[],\"fully_booked\":false,\"story\":\"peter-march-2026\"},{\"id\":\"9e7c0dc74970cf03\",\"start\":\"2026-03-10\",\"end\":\"2026-03-10\",\"days\":1,\"half_last\":false,\"level\":null,\"status\":\"past\",\"places\":null,\"beds\":null,\"day_places\":[],\"fully_booked\":false,\"story\":null},{\"id\":\"bea4d6d869fcfb76\",\"start\":\"2026-03-17\",\"end\":\"2026-03-19\",\"days\":3,\"half_last\":false,\"level\":null,\"status\":\"past\",\"places\":null,\"beds\":null,\"day_places\":[],\"fully_booked\":false,\"story\":null},{\"id\":\"b07f13373c810184\",\"start\":\"2026-04-04\",\"end\":\"2026-04-06\",\"days\":3,\"half_last\":false,\"level\":null,\"status\":\"past\",\"places\":null,\"beds\":null,\"day_places\":[],\"fully_booked\":false,\"story\":null},{\"id\":\"80e70e9c40f71a05\",\"start\":\"2026-04-06\",\"end\":\"2026-04-06\",\"days\":1,\"half_last\":false,\"level\":null,\"status\":\"past\",\"places\":null,\"beds\":null,\"day_places\":[],\"fully_booked\":false,\"story\":null},{\"id\":\"3683f3c30e754c25\",\"start\":\"2026-04-23\",\"end\":\"2026-04-25\",\"days\":3,\"half_last\":false,\"level\":null,\"status\":\"past\",\"places\":null,\"beds\":null,\"day_places\":[],\"fully_booked\":false,\"story\":null},{\"id\":\"ab04660a341d3d43\",\"start\":\"2026-04-30\",\"end\":\"2026-05-02\",\"days\":3,\"half_last\":false,\"level\":null,\"status\":\"past\",\"places\":null,\"beds\":null,\"day_places\":[],\"fully_booked\":false,\"story\":null},{\"id\":\"21603ed9caee1fa6\",\"start\":\"2026-05-14\",\"end\":\"2026-05-17\",\"days\":4,\"half_last\":false,\"level\":null,\"status\":\"past\",\"places\":null,\"beds\":null,\"day_places\":[],\"fully_booked\":false,\"story\":null},{\"id\":\"48e09fc534bea706\",\"start\":\"2026-05-15\",\"end\":\"2026-05-16\",\"days\":2,\"half_last\":false,\"level\":null,\"status\":\"past\",\"places\":null,\"beds\":null,\"day_places\":[],\"fully_booked\":false,\"story\":null},{\"id\":\"e008466f8e423026\",\"start\":\"2026-06-20\",\"end\":\"2026-06-22\",\"days\":3,\"half_last\":false,\"level\":null,\"status\":\"past\",\"places\":null,\"beds\":null,\"day_places\":[],\"fully_booked\":false,\"story\":null},{\"id\":\"ca1932980e532aad\",\"start\":\"2026-09-04\",\"end\":\"2026-09-06\",\"days\":3,\"half_last\":false,\"level\":null,\"status\":\"past\",\"places\":null,\"beds\":null,\"day_places\":[],\"fully_booked\":false,\"story\":null},{\"id\":\"ca677eb0f099b231\",\"start\":\"2026-09-12\",\"end\":\"2026-09-13\",\"days\":2,\"half_last\":false,\"level\":null,\"status\":\"past\",\"places\":null,\"beds\":null,\"day_places\":[],\"fully_booked\":false,\"story\":\"nick-september-2026\"},{\"id\":\"fd9af8b66c669e1f\",\"start\":\"2026-09-26\",\"end\":\"2026-09-27\",\"days\":2,\"half_last\":false,\"level\":null,\"status\":\"past\",\"places\":null,\"beds\":null,\"day_places\":[],\"fully_booked\":false,\"story\":null},{\"id\":\"3d1346fd773bd8f0\",\"start\":\"2026-10-06\",\"end\":\"2026-10-07\",\"days\":2,\"half_last\":false,\"level\":null,\"status\":\"past\",\"places\":null,\"beds\":null,\"day_places\":[],\"fully_booked\":false,\"story\":null},{\"id\":\"54fc1d5e489e2f12\",\"start\":\"2026-10-13\",\"end\":\"2026-10-15\",\"days\":3,\"half_last\":false,\"level\":null,\"status\":\"past\",\"places\":null,\"beds\":null,\"day_places\":[],\"fully_booked\":false,\"story\":null},{\"id\":\"643b4bf1b3849dc1\",\"start\":\"2026-10-22\",\"end\":\"2026-10-23\",\"days\":2,\"half_last\":false,\"level\":null,\"status\":\"past\",\"places\":null,\"beds\":null,\"day_places\":[],\"fully_booked\":false,\"story\":null},{\"id\":\"406658804db06e58\",\"start\":\"2026-11-04\",\"end\":\"2026-11-07\",\"days\":4,\"half_last\":true,\"level\":null,\"status\":\"planned\",\"places\":null,\"beds\":null,\"day_places\":[{\"date\":\"2026-11-04\",\"places\":null,\"fully_booked\":false},{\"date\":\"2026-11-05\",\"places\":null,\"fully_booked\":false},{\"date\":\"2026-11-06\",\"places\":null,\"fully_booked\":false},{\"date\":\"2026-11-07\",\"places\":null,\"fully_booked\":false}],\"fully_booked\":false,\"story\":null},{\"id\":\"cbd0cd61561af633\",\"start\":\"2026-11-19\",\"end\":\"2026-11-19\",\"days\":1,\"half_last\":false,\"level\":null,\"status\":\"planned\",\"places\":null,\"beds\":null,\"day_places\":[{\"date\":\"2026-11-19\",\"places\":null,\"fully_booked\":false}],\"fully_booked\":false,\"story\":null},{\"id\":\"3a3866514ff13786\",\"start\":\"2026-11-23\",\"end\":\"2026-11-23\",\"days\":1,\"half_last\":false,\"level\":null,\"status\":\"planned\",\"places\":null,\"beds\":null,\"day_places\":[{\"date\":\"2026-11-23\",\"places\":null,\"fully_booked\":false}],\"fully_booked\":false,\"story\":null},{\"id\":\"4832c9f007714e69\",\"start\":\"2026-12-21\",\"end\":\"2026-12-21\",\"days\":1,\"half_last\":false,\"level\":null,\"status\":\"planned\",\"places\":null,\"beds\":null,\"day_places\":[{\"date\":\"2026-12-21\",\"places\":null,\"fully_booked\":false}],\"fully_booked\":false,\"story\":null},{\"id\":\"184ff65970a8926c\",\"start\":\"2027-01-02\",\"end\":\"2027-01-02\",\"days\":1,\"half_last\":false,\"level\":null,\"status\":\"planned\",\"places\":null,\"beds\":null,\"day_places\":[{\"date\":\"2027-01-02\",\"places\":null,\"fully_booked\":false}],\"fully_booked\":false,\"story\":null},{\"id\":\"67f0f12d00137543\",\"start\":\"2027-03-19\",\"end\":\"2027-03-19\",\"days\":1,\"half_last\":false,\"level\":null,\"status\":\"planned\",\"places\":null,\"beds\":null,\"day_places\":[{\"date\":\"2027-03-19\",\"places\":null,\"fully_booked\":false}],\"fully_booked\":false,\"story\":null},{\"id\":\"ed9a6bb05bf9cfad\",\"start\":\"2027-03-23\",\"end\":\"2027-03-25\",\"days\":3,\"half_last\":false,\"level\":null,\"status\":\"planned\",\"places\":null,\"beds\":null,\"day_places\":[{\"date\":\"2027-03-23\",\"places\":null,\"fully_booked\":false},{\"date\":\"2027-03-24\",\"places\":null,\"fully_booked\":false},{\"date\":\"2027-03-25\",\"places\":null,\"fully_booked\":false}],\"fully_booked\":false,\"story\":null},{\"id\":\"411f51eed90a0271\",\"start\":\"2027-04-07\",\"end\":\"2027-04-09\",\"days\":3,\"half_last\":false,\"level\":null,\"status\":\"provisional\",\"places\":null,\"beds\":null,\"day_places\":[{\"date\":\"2027-04-07\",\"places\":null,\"fully_booked\":false},{\"date\":\"2027-04-08\",\"places\":null,\"fully_booked\":false},{\"date\":\"2027-04-09\",\"places\":null,\"fully_booked\":false}],\"fully_booked\":false,\"story\":null},{\"id\":\"374033ee7bef4f27\",\"start\":\"2027-04-17\",\"end\":\"2027-04-19\",\"days\":3,\"half_last\":false,\"level\":null,\"status\":\"planned\",\"places\":null,\"beds\":null,\"day_places\":[{\"date\":\"2027-04-17\",\"places\":null,\"fully_booked\":false},{\"date\":\"2027-04-18\",\"places\":null,\"fully_booked\":false},{\"date\":\"2027-04-19\",\"places\":null,\"fully_booked\":false}],\"fully_booked\":false,\"story\":null},{\"id\":\"0fff2b2365a7b350\",\"start\":\"2027-06-01\",\"end\":\"2027-06-03\",\"days\":3,\"half_last\":false,\"level\":null,\"status\":\"provisional\",\"places\":null,\"beds\":null,\"day_places\":[{\"date\":\"2027-06-01\",\"places\":null,\"fully_booked\":false},{\"date\":\"2027-06-02\",\"places\":null,\"fully_booked\":false},{\"date\":\"2027-06-03\",\"places\":null,\"fully_booked\":false}],\"fully_booked\":false,\"story\":null}]},\"stories\":{\"nick-september-2026\":\"https:\\\/\\\/letsrideportugal.com\\\/es\\\/ride-stories\\\/#ride-nick-september-2026\",\"peter-march-2026\":\"https:\\\/\\\/letsrideportugal.com\\\/es\\\/ride-stories\\\/#peter-story\"}}<\/script><\/div><\/section><\/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-f1170001 elementor-widget elementor-widget-shortcode\" data-id=\"f1170001\" data-element_type=\"widget\" id=\"lrp-tour-flight-planner\" data-widget_type=\"shortcode.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\"><div data-compact=\"1\" data-lang=\"es\" lang=\"es-ES\" class=\"lrp-fp\" data-mode=\"planner\" data-api=\"https:\/\/letsrideportugal.com\/es\/wp-json\/lrp-flights\/v1\/\" data-nonce=\"\" data-preview=\"0\" data-initial-airport=\"\" data-initial-date=\"\" data-planner-url=\"https:\/\/letsrideportugal.com\/es\/flight-planner\/\" data-tours-url=\"https:\/\/letsrideportugal.com\/es\/fechas-de-rutas\/\"><p>Buscando tu ruta a Faro\u2026<\/p><\/div><\/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-f1170018 elementor-widget elementor-widget-html\" data-id=\"f1170018\" data-element_type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<style>\n.lrp-av-flight-links .lrp-av-intro-action{display:flex;align-items:center;flex-wrap:wrap;gap:12px}\n.lrp-av-flight-links .lrp-find-flights{gap:16px;background:transparent;color:var(--lrp-gold)!important;border-color:#8e633e}\n.lrp-av-flight-links .lrp-find-flights:hover{background:#392d1d;border-color:var(--lrp-gold)}\n.lrp-av-flight-links .lrp-tour-flight-link{display:flex;align-items:center;gap:12px;min-height:48px;margin-top:20px;padding:14px 0 0;border-top:1px solid var(--lrp-line);color:var(--lrp-gold)!important;font-size:14px;text-decoration:none}\n.lrp-av-flight-links .lrp-tour-flight-link .lrp-flight-link-plane{display:block;width:32px!important;height:32px!important;min-width:32px;flex:0 0 32px;stroke-width:1.9;transition:transform .18s ease}\n.lrp-av-flight-links .lrp-tour-flight-link:is(:hover,:focus-visible) .lrp-flight-link-plane{transform:translate(2px,-2px)}\n.lrp-av-flight-links .lrp-tour-flight-link:is(:hover,:focus-visible)>span{text-decoration:underline;text-underline-offset:5px;text-decoration-thickness:1px}\n@media(prefers-reduced-motion:reduce){.lrp-av-flight-links .lrp-flight-link-plane{transition:none!important;transform:none!important}}\n.lrp-av-flight-links .lrp-flight-link-arrow{font-size:22px;line-height:1;transition:transform .2s ease}\n.lrp-av-flight-links :is(.lrp-tour-flight-link,.lrp-find-flights):hover .lrp-flight-link-arrow{transform:translate(2px,2px)}\n.lrp-av-flight-links .lrp-av-booked .lrp-tour-flight-link{display:none!important}\n#lrp-tour-flight-planner{scroll-margin-top:130px;background:#171815}\n#lrp-tour-flight-planner:focus-visible{outline:2px solid #ffbd66;outline-offset:-3px}\n#lrp-tour-flight-planner .lrp-flight-trip-context{margin:0;padding:18px 32px 0;color:#d0d4c7;background:#171815;font-size:13px;line-height:1.6}\n@media(max-width:760px){#lrp-tour-flight-planner{scroll-margin-top:100px}#lrp-tour-flight-planner .lrp-flight-trip-context{padding:18px 18px 0}}\n@media(prefers-reduced-motion:reduce){.lrp-av-flight-links .lrp-flight-link-arrow{transition:none}}\n\n<\/style>\n<script>\n\/* Draft-page navigation for the installed LRP Flight Planner 0.1.0. *\/\n(() => {\n  'use strict';\n  const setup = () => {\n    const tr=(key,vars={})=>window.LRPFlightText?.tr(key,vars)||String({\"load\": \"Finding your way to Faro\u2026\", \"auth\": \"Please sign in to view this preview.\", \"loadError\": \"The flight guide could not be loaded. Please try again.\", \"prepared\": \"The flight guide is being prepared. Please check back soon.\", \"kicker\": \"THE ALGARVE IS CLOSER THAN YOU THINK\", \"title\": \"Find your flight.\", \"subtitle\": \"We\u2019ll find the trails.\", \"intro1\": \"One direct flight. A whole different world.\", \"intro2\": \"Explore routes to Faro and start planning your ride.\", \"directOnly\": \"Direct flights only\", \"trip\": \"Your tour travel dates:\", \"flyTo\": \"fly to Faro\", \"flyHome\": \"fly home\", \"returnFlights\": \"See return flights\", \"exploreAria\": \"Explore direct flights to Faro\", \"mapKicker\": \"YOUR ROUTE TO THE RIDE\", \"europe\": \"Europe\", \"allRoutes\": \"All routes\", \"allRoutesAria\": \"Show all routes\", \"mapAria\": \"Airport route map. Select an airport or use the airport selector beside the map.\", \"loadingMap\": \"Loading the route map\u2026\", \"selectAirport\": \"Select a departure airport\", \"airportCount\": \"airports \u00b7 one great destination\", \"departQuestion\": \"Where are you flying from?\", \"searchAirport\": \"Search city or airport\", \"searchAirportAria\": \"Filter airports by city or airport code\", \"departureAirport\": \"Departure airport\", \"monthQuestion\": \"When do you want to fly?\", \"direction\": \"Flight direction\", \"toFaro\": \"To Faro\", \"fromFaro\": \"From Faro\", \"exploreDates\": \"Explore flight dates\", \"airlineBooking\": \"Your flight is booked directly with the airline.\", \"scheduleKicker\": \"MAKE IT A DATE\", \"scheduleTitle\": \"The way to your next ride.\", \"airline\": \"Airline\", \"allAirlines\": \"All airlines\", \"previous\": \"Previous month\", \"next\": \"Next month\", \"flightDates\": \"Flight dates\", \"timesListed\": \"Times listed\", \"dateListed\": \"Date listed\", \"wholeMonth\": \"Show the whole month\", \"moreDates\": \"Show more flight dates\", \"disclaimer\": \"All times are local to each airport. Schedules may change. Check flight details and prices with the airline before booking.\", \"ctaKicker\": \"FROM ARRIVALS TO ADVENTURE\", \"ctaTitle\": \"We\u2019ll take it from Faro.\", \"ctaText\": \"Airport transfers, good food and great trails. Explore the ride that fits your trip.\", \"ctaButton\": \"Find your riding dates\", \"updated\": \"Flight guide updated\", \"guide\": \"Direct flight schedule guide\", \"noAirport\": \"No matching airports\", \"chooseAirport\": \"Choose an airport below\", \"homeQuestion\": \"Where are you flying home to?\", \"homeAirport\": \"Return destination airport\", \"departureKicker\": \"YOUR DEPARTURE\", \"leavingKicker\": \"LEAVING THE ALGARVE\", \"routeAirlines\": \"AIRLINES ON THIS ROUTE\", \"loadingDates\": \"Loading flight dates\u2026\", \"listedTimes\": \"flight times listed\", \"listedDate\": \"flight date listed, times to be added\", \"noFlights\": \"no flights listed\", \"unchecked\": \"schedule not yet checked\", \"flightSingle\": \"flight\", \"flightPlural\": \"flights\", \"datePlural\": \"dates\", \"noSelection\": \"No listed flights for this selection.\", \"noDates\": \"No flights listed for these dates.\", \"inProgress\": \"We\u2019re still filling in these dates.\", \"otherAirline\": \"Try another airline or show all airlines for this route.\", \"otherDate\": \"Try another date or departure airport. Please also check the airline\u2019s latest schedule.\", \"incomplete\": \"This part of the flight guide is not complete yet. Try another month or airport, or check directly with the airline.\", \"listedDirect\": \"A direct flight is listed\", \"timesFollow\": \"Flight times to follow\", \"checkAirline\": \"Check the airline for flight times.\", \"timeTBC\": \"Time TBC\", \"airlineTBC\": \"Airline to be confirmed\", \"direct\": \"direct\", \"arrivalDay\": \"Arrival day needs confirmation with the airline.\", \"resultsFor\": \"{n} results for {airport}, {date}.\", \"detailsPending\": \"Some flight details for this selection are still being added.\", \"mapFallback\": \"Your next ride starts in Faro.\", \"mapChoose\": \"Choose your departure airport to explore direct flights.\", \"mapKeys\": \"Direct flight routes to Faro. Use arrow keys to explore airports and Enter to select.\", \"selectAirportAction\": \"select departure airport\", \"mapHere\": \"YOUR RIDE STARTS HERE\", \"islandAria\": \"Atlantic island airports\", \"atlanticAlso\": \"Also in the Atlantic\", \"azores\": \"Azores \u00b7 PDL\", \"iceland\": \"Iceland \u00b7 KEF\", \"directFaro\": \"Direct to Faro\", \"daySingle\": \"day\", \"dayPlural\": \"days\", \"fullPlanner\": \"Open the full Flight Planner\", \"findFlights\": \"Find flights\", \"flightForTour\": \"Find flights for this tour\", \"zoomIn\": \"Zoom in on map\", \"zoomOut\": \"Zoom out on map\", \"zoomReset\": \"Reset map zoom\", \"zoomLabel\": \"Map zoom\", \"zoomHint\": \"Scroll to zoom \u00b7 Drag to explore\", \"halfDayText\": \"Your last ride is a half day on {date}. Please confirm return-flight timing with us.\", \"travelText\": \"Suggested travel days: arrive the day before riding and fly home the day after your last ride.\", \"duration1\": \"1 Day\", \"duration2\": \"2 Days\", \"duration3\": \"3 Days\", \"duration4\": \"4 Days\", \"dateLabel\": \"Preferred Start Date (dd\/mm\/yyyy)\", \"dateSingle\": \"date\", \"flightFew\": \"flights\", \"dateFew\": \"dates\", \"dayFew\": \"days\", \"locale\": \"en-GB\", \"atlantic\": \"Atlantic\"}[key]||key).replace(\/\\{(\\w+)\\}\/g,(_,k)=>String(vars[k]??''));\n    const target = document.getElementById('lrp-tour-flight-planner');\n    const calendar = document.querySelector('.lrp-availability');\n    if (!target || !calendar || target.dataset.flightLinksReady) return;\n    target.dataset.flightLinksReady = '1';\n    calendar.classList.add('lrp-av-flight-links');\n    target.tabIndex = -1;\n    target.setAttribute('role', 'region');\n    target.setAttribute('aria-label', tr('fullPlanner'));\n    let config = {};\n    try { config = JSON.parse(calendar.querySelector('.lrp-av-config')?.textContent || '{}'); } catch (_) {}\n    const iso = value => \/^\\d{4}-\\d{2}-\\d{2}$\/.test(value || '');\n    const shift = (date, days) => {\n      const value = new Date(date + 'T12:00:00Z');\n      value.setUTCDate(value.getUTCDate() + days);\n      return value.toISOString().slice(0, 10);\n    };\n    const dateLabel = date => new Intl.DateTimeFormat(window.LRPFlightText?.locale||document.documentElement.lang||'en-GB', {day:'numeric', month:'short', timeZone:'UTC'}).format(new Date(date + 'T12:00:00Z'));\n    const scroll = () => {\n      target.focus({preventScroll:true});\n      target.scrollIntoView({behavior:matchMedia('(prefers-reduced-motion: reduce)').matches ? 'auto' : 'smooth', block:'start'});\n    };\n    const itinerary = card => {\n      const id = card.id.split('-tour-').pop();\n      const enquiry = card.querySelector('a[href*=\"lrp_tour_mode=stay\"]') || card.querySelector('a[href*=\"lrp_tour_start=\"]');\n      const url = enquiry ? new URL(enquiry.href, location.href) : null;\n      const tour = config.initial?.tours?.find(item => String(item.id) === id);\n      const stay = url?.searchParams.get('lrp_tour_mode') === 'stay';\n      const start = (stay && url.searchParams.get('lrp_tour_start')) || tour?.start || url?.searchParams.get('lrp_tour_start');\n      const end = (stay && url.searchParams.get('lrp_tour_end')) || tour?.end || url?.searchParams.get('lrp_tour_end');\n      if (!iso(start) || !iso(end)) return null;\n      const overrides = window.lrpFpConfig?.travelOverrides || {};\n      const candidate = Array.isArray(overrides) ? overrides.find(item => String(item.tourId) === id) : overrides[id];\n      const override = candidate && (candidate.start || candidate.tourStart) === start && (candidate.end || candidate.tourEnd) === end ? candidate : null;\n      const arrival = override?.arrival || override?.outbound || tour?.arrival || shift(start, -1);\n      const departure = override?.departure || override?.return || tour?.departure || shift(end, 1);\n      return iso(arrival) && iso(departure) ? {arrival, departure, halfDay:!!override?.halfDayTiming} : null;\n    };\n    const openTour = card => {\n      if ((card.classList.contains('lrp-av-booked') || card.classList.contains('lrp-av-past')) || !card.isConnected) return;\n      const trip = itinerary(card);\n      const root = target.querySelector('.lrp-fp[data-mode=\"planner\"]');\n      if (trip && root && window.LRPFlightPlanner?.boot) {\n        const airport = root.querySelector('select[id$=\"-airport\"]')?.value || root.dataset.initialAirport;\n        const url = new URL(location.href);\n        url.searchParams.set('arrival', trip.arrival);\n        url.searchParams.set('departure', trip.departure);\n        url.searchParams.set('direction', 'to-faro');\n        url.searchParams.set('month', trip.arrival.slice(0, 7));\n        url.searchParams.delete('date');\n        if (airport) url.searchParams.set('airport', airport);\n        url.hash = target.id;\n        history.replaceState(history.state, '', url.href);\n        const next = root.cloneNode(false);\n        next.classList.remove('fp-ready');\n        next.dataset.initialDate = trip.arrival;\n        if (airport) next.dataset.initialAirport = airport;\n        root.replaceWith(next);\n        window.LRPFlightPlanner.boot();\n        target.querySelector('.lrp-flight-trip-context')?.remove();\n        const context = document.createElement('p');\n        context.className = 'lrp-flight-trip-context';\n        context.textContent = trip.halfDay\n          ? tr('halfDayText',{date:dateLabel(trip.departure)})\n          : tr('travelText');\n        target.prepend(context);\n      }\n      scroll();\n    };\n    const makeLink = (text, className) => {\n      const link = document.createElement('a');\n      link.href = '#' + target.id;\n      link.className = className;\n      const label = document.createElement('span');\n      label.textContent = text;\n      const arrow = document.createElement('span');\n      arrow.className = 'lrp-flight-link-arrow';\n      arrow.setAttribute('aria-hidden', 'true');\n      arrow.textContent = '\u2198';\n      if (className === 'lrp-tour-flight-link') {\n        \/\/ Lucide Plane, v1.17.0, ISC license. Matches the approved preview.\n        const ns = 'http:\/\/www.w3.org\/2000\/svg';\n        const plane = document.createElementNS(ns, 'svg');\n        const attrs = {class:'lrp-flight-link-plane',width:'32',height:'32',viewBox:'0 0 24 24',fill:'none',stroke:'currentColor','stroke-width':'1.9','stroke-linecap':'round','stroke-linejoin':'round','aria-hidden':'true',focusable:'false'};\n        Object.entries(attrs).forEach(([name, value]) => plane.setAttribute(name, value));\n        const path = document.createElementNS(ns, 'path');\n        path.setAttribute('d', 'M17.8 19.2 16 11l3.5-3.5C21 6 21.5 4 21 3c-1-.5-3 0-4.5 1.5L13 8 4.8 6.2c-.5-.1-.9.1-1.1.5l-.3.5c-.2.5-.1 1 .3 1.3L9 12l-2 3H4l-1 1 3 2 2 3 1-1v-3l3-2 3.5 5.3c.3.4.8.5 1.3.3l.5-.2c.4-.3.6-.7.5-1.2z');\n        plane.append(path);\n        link.append(plane, label);\n      } else {\n        link.append(label, arrow);\n      }\n      return link;\n    };\n    const action = calendar.querySelector('.lrp-av-intro-action');\n    if (action && !action.querySelector('.lrp-find-flights')) {\n      const link = makeLink(tr('findFlights'), 'lrp-av-cta lrp-find-flights');\n      link.addEventListener('click', event => {event.preventDefault(); scroll();});\n      action.append(link);\n    }\n    const updateCards = () => calendar.querySelectorAll('.lrp-av-card').forEach(card => {\n      const previous = card.querySelector('.lrp-tour-flight-link');\n      if ((card.classList.contains('lrp-av-booked') || card.classList.contains('lrp-av-past')) || !card.id.includes('-tour-')) {\n        previous?.remove();\n        return;\n      }\n      if (previous) return;\n      const link = makeLink(tr('flightForTour'), 'lrp-tour-flight-link');\n      link.addEventListener('click', event => {event.preventDefault(); openTour(card);});\n      card.append(link);\n    });\n    updateCards();\n    const list = calendar.querySelector('.lrp-av-list');\n    if (list) new MutationObserver(updateCards).observe(list, {childList:true, subtree:true, attributes:true, attributeFilter:['class']});\n    \/\/ The standalone shortcode owns the planner; keep a single H1 on this combined page.\n    const heading = () => {\n      const title = target.querySelector('.fp-heading h1');\n      if (!title) return;\n      const replacement = document.createElement('h2');\n      replacement.innerHTML = title.innerHTML;\n      title.replaceWith(replacement);\n    };\n    heading();\n    new MutationObserver(heading).observe(target, {childList:true, subtree:true});\n  };\n  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', setup, {once:true}); else setup();\n})();\n\n<\/script>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-f1170920 elementor-widget elementor-widget-html\" data-id=\"f1170920\" data-element_type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<style>\n\/* Flight Planner draft enhancement; no global map or page-scroll overrides. *\/\n.lrp-fp .lrp-map-zoom-enabled .fp-map-svg{touch-action:pan-y pinch-zoom}\n.lrp-fp .lrp-map-is-zoomed .fp-map-svg{cursor:grab;touch-action:none}\n.lrp-fp .lrp-map-is-dragging .fp-map-svg,.lrp-fp .lrp-map-is-dragging .fp-airport-point{cursor:grabbing}\n.lrp-fp .lrp-map-is-dragging{user-select:none}\n.lrp-fp .lrp-map-zoom-enabled :is(.fp-map-land path,.fp-route-arc){vector-effect:non-scaling-stroke}\n.lrp-fp .lrp-map-zoom-dock{position:absolute;right:20px;top:94px;z-index:2;display:flex;flex-direction:column;align-items:flex-end;gap:7px;pointer-events:none}\n.lrp-fp .lrp-map-zoom-dock[hidden]{display:none}\n.lrp-fp .lrp-map-zoom-controls{display:flex;align-items:center;gap:0;pointer-events:auto;border:1px solid #687253;border-radius:11px;background:#17221eeb;box-shadow:0 4px 18px #0004;overflow:visible}\n.lrp-fp .lrp-map-zoom-button{display:grid;place-items:center;min-width:40px;width:40px;height:42px;min-height:42px;padding:0;border:0;border-right:1px solid #59654c;border-radius:0;background:transparent;color:#f5f2e9;font-size:23px;font-weight:400;line-height:1;transition:background .15s,color .15s}\n.lrp-fp .lrp-map-zoom-button:first-child{border-radius:10px 0 0 10px}\n.lrp-fp .lrp-map-zoom-button:hover:not(:disabled){background:#344331;color:#ffb57f}\n.lrp-fp .lrp-map-zoom-button:disabled{opacity:.32;cursor:default}\n.lrp-fp .lrp-map-zoom-button:focus-visible{position:relative;z-index:1;outline:3px solid #ffb57f;outline-offset:2px}\n.lrp-fp .lrp-map-zoom-level{min-width:48px;padding:0 9px;color:#c9d1bc;font-size:10px;line-height:1;white-space:nowrap}\n.lrp-fp .lrp-map-zoom-hint{margin:0!important;padding:3px 7px;border-radius:5px;background:#152323d9;color:#c0c9b8!important;font-size:9px!important;line-height:1.5!important;text-shadow:0 1px 3px #000}\n@media(max-width:760px){.lrp-fp .lrp-map-zoom-dock{right:12px;top:84px}.lrp-fp .lrp-map-zoom-button{width:42px;min-width:42px;height:44px;min-height:44px}.lrp-fp .lrp-map-zoom-hint{font-size:9px!important}}\n@media(prefers-reduced-motion:reduce){.lrp-fp .lrp-map-zoom-button{transition:none}}\n\n<\/style>\n<script>\n\/* Progressive map navigation for the private Flight Planner drafts. *\/\n(() => {\n  'use strict';\n  if (window.LRPFlightMapZoom) { window.LRPFlightMapZoom.boot(); return; }\n  const tr=(key,vars={})=>window.LRPFlightText?.tr(key,vars)||String({\"load\": \"Finding your way to Faro\u2026\", \"auth\": \"Please sign in to view this preview.\", \"loadError\": \"The flight guide could not be loaded. Please try again.\", \"prepared\": \"The flight guide is being prepared. Please check back soon.\", \"kicker\": \"THE ALGARVE IS CLOSER THAN YOU THINK\", \"title\": \"Find your flight.\", \"subtitle\": \"We\u2019ll find the trails.\", \"intro1\": \"One direct flight. A whole different world.\", \"intro2\": \"Explore routes to Faro and start planning your ride.\", \"directOnly\": \"Direct flights only\", \"trip\": \"Your tour travel dates:\", \"flyTo\": \"fly to Faro\", \"flyHome\": \"fly home\", \"returnFlights\": \"See return flights\", \"exploreAria\": \"Explore direct flights to Faro\", \"mapKicker\": \"YOUR ROUTE TO THE RIDE\", \"europe\": \"Europe\", \"allRoutes\": \"All routes\", \"allRoutesAria\": \"Show all routes\", \"mapAria\": \"Airport route map. Select an airport or use the airport selector beside the map.\", \"loadingMap\": \"Loading the route map\u2026\", \"selectAirport\": \"Select a departure airport\", \"airportCount\": \"airports \u00b7 one great destination\", \"departQuestion\": \"Where are you flying from?\", \"searchAirport\": \"Search city or airport\", \"searchAirportAria\": \"Filter airports by city or airport code\", \"departureAirport\": \"Departure airport\", \"monthQuestion\": \"When do you want to fly?\", \"direction\": \"Flight direction\", \"toFaro\": \"To Faro\", \"fromFaro\": \"From Faro\", \"exploreDates\": \"Explore flight dates\", \"airlineBooking\": \"Your flight is booked directly with the airline.\", \"scheduleKicker\": \"MAKE IT A DATE\", \"scheduleTitle\": \"The way to your next ride.\", \"airline\": \"Airline\", \"allAirlines\": \"All airlines\", \"previous\": \"Previous month\", \"next\": \"Next month\", \"flightDates\": \"Flight dates\", \"timesListed\": \"Times listed\", \"dateListed\": \"Date listed\", \"wholeMonth\": \"Show the whole month\", \"moreDates\": \"Show more flight dates\", \"disclaimer\": \"All times are local to each airport. Schedules may change. Check flight details and prices with the airline before booking.\", \"ctaKicker\": \"FROM ARRIVALS TO ADVENTURE\", \"ctaTitle\": \"We\u2019ll take it from Faro.\", \"ctaText\": \"Airport transfers, good food and great trails. Explore the ride that fits your trip.\", \"ctaButton\": \"Find your riding dates\", \"updated\": \"Flight guide updated\", \"guide\": \"Direct flight schedule guide\", \"noAirport\": \"No matching airports\", \"chooseAirport\": \"Choose an airport below\", \"homeQuestion\": \"Where are you flying home to?\", \"homeAirport\": \"Return destination airport\", \"departureKicker\": \"YOUR DEPARTURE\", \"leavingKicker\": \"LEAVING THE ALGARVE\", \"routeAirlines\": \"AIRLINES ON THIS ROUTE\", \"loadingDates\": \"Loading flight dates\u2026\", \"listedTimes\": \"flight times listed\", \"listedDate\": \"flight date listed, times to be added\", \"noFlights\": \"no flights listed\", \"unchecked\": \"schedule not yet checked\", \"flightSingle\": \"flight\", \"flightPlural\": \"flights\", \"datePlural\": \"dates\", \"noSelection\": \"No listed flights for this selection.\", \"noDates\": \"No flights listed for these dates.\", \"inProgress\": \"We\u2019re still filling in these dates.\", \"otherAirline\": \"Try another airline or show all airlines for this route.\", \"otherDate\": \"Try another date or departure airport. Please also check the airline\u2019s latest schedule.\", \"incomplete\": \"This part of the flight guide is not complete yet. Try another month or airport, or check directly with the airline.\", \"listedDirect\": \"A direct flight is listed\", \"timesFollow\": \"Flight times to follow\", \"checkAirline\": \"Check the airline for flight times.\", \"timeTBC\": \"Time TBC\", \"airlineTBC\": \"Airline to be confirmed\", \"direct\": \"direct\", \"arrivalDay\": \"Arrival day needs confirmation with the airline.\", \"resultsFor\": \"{n} results for {airport}, {date}.\", \"detailsPending\": \"Some flight details for this selection are still being added.\", \"mapFallback\": \"Your next ride starts in Faro.\", \"mapChoose\": \"Choose your departure airport to explore direct flights.\", \"mapKeys\": \"Direct flight routes to Faro. Use arrow keys to explore airports and Enter to select.\", \"selectAirportAction\": \"select departure airport\", \"mapHere\": \"YOUR RIDE STARTS HERE\", \"islandAria\": \"Atlantic island airports\", \"atlanticAlso\": \"Also in the Atlantic\", \"azores\": \"Azores \u00b7 PDL\", \"iceland\": \"Iceland \u00b7 KEF\", \"directFaro\": \"Direct to Faro\", \"daySingle\": \"day\", \"dayPlural\": \"days\", \"fullPlanner\": \"Open the full Flight Planner\", \"findFlights\": \"Find flights\", \"flightForTour\": \"Find flights for this tour\", \"zoomIn\": \"Zoom in on map\", \"zoomOut\": \"Zoom out on map\", \"zoomReset\": \"Reset map zoom\", \"zoomLabel\": \"Map zoom\", \"zoomHint\": \"Scroll to zoom \u00b7 Drag to explore\", \"halfDayText\": \"Your last ride is a half day on {date}. Please confirm return-flight timing with us.\", \"travelText\": \"Suggested travel days: arrive the day before riding and fly home the day after your last ride.\", \"duration1\": \"1 Day\", \"duration2\": \"2 Days\", \"duration3\": \"3 Days\", \"duration4\": \"4 Days\", \"dateLabel\": \"Preferred Start Date (dd\/mm\/yyyy)\", \"dateSingle\": \"date\", \"flightFew\": \"flights\", \"dateFew\": \"dates\", \"dayFew\": \"days\", \"locale\": \"en-GB\", \"atlantic\": \"Atlantic\"}[key]||key).replace(\/\\{(\\w+)\\}\/g,(_,k)=>String(vars[k]??''));\n  const instances = new WeakMap();\n  const MIN = 1, MAX = 8, STEP = 1.5;\n  const clamp = (n, lo, hi) => Math.max(lo, Math.min(hi, n));\n  const pointPosition = node => {\n    const match = (node?.getAttribute('transform') || '').match(\/translate\\(\\s*([-\\d.e+]+)[,\\s]+([-\\d.e+]+)\\s*\\)\/i);\n    return match ? {x:Number(match[1]), y:Number(match[2])} : null;\n  };\n  let instanceNumber = 0;\n  const enhance = map => {\n    if (instances.has(map)) { instances.get(map).adopt(); return; }\n    const panel = map.closest('.fp-map-panel');\n    if (!panel) return;\n    let svg = null, width = 920, height = 650;\n    let view = {x:0, y:0, k:1}, markers = [], countryLabels = [], drag = null, suppressUntil = 0;\n    const controls = document.createElement('div');\n    controls.className = 'lrp-map-zoom-controls';\n    controls.setAttribute('role', 'group');\n    controls.setAttribute('aria-label', tr('zoomLabel'));\n    const makeButton = (label, text, action) => {\n      const button = document.createElement('button');\n      button.type = 'button'; button.className = 'lrp-map-zoom-button';\n      button.setAttribute('aria-label', label); button.title = label;\n      button.textContent = text; button.addEventListener('click', action);\n      controls.append(button); return button;\n    };\n    const inside = point => point && point.x >= view.x && point.x <= view.x + width\/view.k && point.y >= view.y && point.y <= view.y + height\/view.k;\n    const selectedPosition = () => pointPosition(svg?.querySelector('.fp-point-selected'));\n    const apply = () => {\n      if (!svg) return;\n      view.k = clamp(view.k, MIN, MAX);\n      view.x = clamp(view.x, 0, width - width\/view.k);\n      view.y = clamp(view.y, 0, height - height\/view.k);\n      svg.setAttribute('viewBox', [view.x, view.y, width\/view.k, height\/view.k].map(n => Number(n.toFixed(6))).join(' '));\n      markers.forEach(({node, original}) => node.setAttribute('transform', original + ' scale(' + (1\/view.k) + ')'));\n      countryLabels.forEach(({node, x, y, original}) => node.setAttribute('transform', original + ' translate(' + x + ' ' + y + ') scale(' + (1\/view.k) + ') translate(' + (-x) + ' ' + (-y) + ')'));\n      map.classList.toggle('lrp-map-is-zoomed', view.k > MIN + .001);\n      zoomIn.disabled = view.k >= MAX - .001;\n      zoomOut.disabled = resetButton.disabled = view.k <= MIN + .001;\n      status.textContent = Math.round(view.k*100) + '%';\n    };\n    const center = point => {\n      if (!point) return;\n      view.x = point.x - width\/view.k\/2;\n      view.y = point.y - height\/view.k\/2;\n    };\n    const zoom = (next, point, fraction = {x:.5, y:.5}) => {\n      next = clamp(next, MIN, MAX);\n      if (!svg || Math.abs(next - view.k) < .00001) return false;\n      point ||= {x:view.x + width\/view.k\/2, y:view.y + height\/view.k\/2};\n      view.k = next;\n      view.x = point.x - fraction.x*width\/view.k;\n      view.y = point.y - fraction.y*height\/view.k;\n      apply(); return true;\n    };\n    const reset = () => {view = {x:0, y:0, k:1}; apply();};\n    const zoomByButton = direction => {\n      const selected = selectedPosition();\n      zoom(direction > 0 ? view.k*STEP : view.k\/STEP, direction > 0 && inside(selected) ? selected : null);\n    };\n    const zoomIn = makeButton(tr('zoomIn'), '+', () => zoomByButton(1));\n    const zoomOut = makeButton(tr('zoomOut'), '\u2212', () => zoomByButton(-1));\n    const resetButton = makeButton(tr('zoomReset'), '\u21ba', reset);\n    const status = document.createElement('output');\n    status.className = 'lrp-map-zoom-level'; status.setAttribute('aria-label', tr('zoomLabel'));\n    controls.append(status);\n    const hint = document.createElement('p');\n    hint.className = 'lrp-map-zoom-hint'; hint.id = 'lrp-map-zoom-hint-' + (++instanceNumber);\n    hint.textContent = tr('zoomHint');\n    const dock = document.createElement('div');\n    dock.className = 'lrp-map-zoom-dock'; dock.append(controls, hint);\n    panel.append(dock);\n    map.classList.add('lrp-map-zoom-enabled');\n    const adopt = () => {\n      const next = map.querySelector('svg.fp-map-svg');\n      if (next === svg) return;\n      svg = next; drag = null; map.classList.remove('lrp-map-is-dragging');\n      dock.hidden = !svg;\n      if (!svg) return;\n      const box = (svg.getAttribute('viewBox') || '').trim().split(\/[ ,]+\/).map(Number);\n      if (box.length === 4 && box[2] > 0 && box[3] > 0) {width = box[2]; height = box[3];}\n      markers = [...svg.querySelectorAll('.fp-airport-point,.fp-faro-point')].map(node => ({node, original:node.getAttribute('transform') || ''}));\n      countryLabels = [...svg.querySelectorAll('.fp-map-country-labels text')].map(node => ({node, x:Number(node.getAttribute('x')) || 0, y:Number(node.getAttribute('y')) || 0, original:node.getAttribute('transform') || ''}));\n      svg.setAttribute('tabindex', '0');\n      svg.setAttribute('aria-describedby', hint.id);\n      const selected = selectedPosition();\n      if (view.k > 1 && selected && !inside(selected)) center(selected);\n      apply();\n    };\n    \/\/ SVG uses xMidYMid\/meet: account for its letterboxed area, not just the element box.\n    const screen = event => {\n      const rect = svg.getBoundingClientRect();\n      const scale = Math.min(rect.width\/width, rect.height\/height);\n      if (!(scale > 0)) return null;\n      const drawnWidth = width*scale, drawnHeight = height*scale;\n      const fx = (event.clientX - rect.left - (rect.width-drawnWidth)\/2)\/drawnWidth;\n      const fy = (event.clientY - rect.top - (rect.height-drawnHeight)\/2)\/drawnHeight;\n      return {x:clamp(fx, 0, 1), y:clamp(fy, 0, 1), scale:scale*view.k, onMap:fx >= 0 && fx <= 1 && fy >= 0 && fy <= 1};\n    };\n    map.addEventListener('wheel', event => {\n      if (!svg || !svg.contains(event.target) || event.ctrlKey || event.metaKey || !event.deltaY) return;\n      const cursor = screen(event); if (!cursor?.onMap) return;\n      const dy = event.deltaY * (event.deltaMode === 1 ? 16 : event.deltaMode === 2 ? 300 : 1);\n      const factor = Math.exp(-clamp(dy, -120, 120)*.003);\n      const point = {x:view.x + cursor.x*width\/view.k, y:view.y + cursor.y*height\/view.k};\n      \/\/ At either limit, let normal page scrolling continue.\n      if (zoom(view.k*factor, point, cursor)) event.preventDefault();\n    }, {passive:false});\n    map.addEventListener('pointerdown', event => {\n      if (!svg || !svg.contains(event.target) || event.button !== 0) return;\n      suppressUntil = 0;\n      if (view.k <= 1 || drag) return;\n      const cursor = screen(event); if (!cursor?.onMap) return;\n      drag = {id:event.pointerId, x:event.clientX, y:event.clientY, originX:view.x, originY:view.y, scale:cursor.scale, moved:false};\n    });\n    map.addEventListener('pointermove', event => {\n      if (!drag || event.pointerId !== drag.id) return;\n      const dx = event.clientX - drag.x, dy = event.clientY - drag.y;\n      if (!drag.moved && Math.hypot(dx, dy) < 5) return;\n      if (!drag.moved) {\n        drag.moved = true; map.classList.add('lrp-map-is-dragging');\n        try {map.setPointerCapture(event.pointerId);} catch (_) {}\n      }\n      event.preventDefault();\n      view.x = drag.originX - dx\/drag.scale; view.y = drag.originY - dy\/drag.scale;\n      apply();\n    });\n    const finishDrag = event => {\n      if (!drag || event.pointerId !== drag.id) return;\n      if (drag.moved) suppressUntil = Date.now() + 600;\n      try {if (map.hasPointerCapture?.(event.pointerId)) map.releasePointerCapture(event.pointerId);} catch (_) {}\n      drag = null; map.classList.remove('lrp-map-is-dragging');\n    };\n    map.addEventListener('pointerup', finishDrag);\n    map.addEventListener('pointercancel', finishDrag);\n    map.addEventListener('lostpointercapture', finishDrag);\n    map.addEventListener('pointerleave', event => {if (drag && !drag.moved) finishDrag(event);});\n    map.addEventListener('click', event => {\n      if (event.detail !== 0 && Date.now() < suppressUntil) {\n        event.preventDefault(); event.stopImmediatePropagation(); suppressUntil = 0;\n      }\n    }, true);\n    map.addEventListener('focusin', event => {\n      const point = event.target.closest?.('.fp-airport-point');\n      const position = pointPosition(point);\n      if (view.k > 1 && position && !inside(position)) {center(position); apply();}\n    });\n    map.addEventListener('keydown', event => {\n      if (!svg || !svg.contains(event.target) || event.ctrlKey || event.metaKey || event.altKey) return;\n      if (event.key === '+' || event.key === '=') {event.preventDefault(); zoomByButton(1);}\n      else if (event.key === '-') {event.preventDefault(); zoomByButton(-1);}\n      else if (event.key === '0' || event.key === 'Escape') {event.preventDefault(); reset();}\n      \/\/ Airport groups already own their arrows\/Home\/End; only pan from SVG background focus.\n      else if (event.target === svg && view.k > 1 && ['ArrowLeft','ArrowRight','ArrowUp','ArrowDown'].includes(event.key)) {\n        event.preventDefault();\n        if (event.key === 'ArrowLeft') view.x -= width\/view.k*.15;\n        if (event.key === 'ArrowRight') view.x += width\/view.k*.15;\n        if (event.key === 'ArrowUp') view.y -= height\/view.k*.15;\n        if (event.key === 'ArrowDown') view.y += height\/view.k*.15;\n        apply();\n      }\n    });\n    panel.addEventListener('click', event => {\n      if (event.target.closest?.('[data-action=\"reset-map\"]')) reset();\n    }, true);\n    instances.set(map, {adopt});\n    new MutationObserver(adopt).observe(map, {childList:true});\n    adopt();\n  };\n  const boot = () => document.querySelectorAll('.lrp-fp[data-mode] .fp-map').forEach(enhance);\n  window.LRPFlightMapZoom = {boot};\n  const start = () => {\n    boot();\n    \/\/ Tour selection can replace the whole planner root; attach to new maps as they appear.\n    new MutationObserver(records => {\n      if (records.some(record => [...record.addedNodes].some(node => node.nodeType === 1 && (node.matches?.('.lrp-fp[data-mode],.fp-map') || node.querySelector?.('.lrp-fp[data-mode],.fp-map'))))) boot();\n    }).observe(document.body, {childList:true, subtree:true});\n  };\n  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', start, {once:true}); else start();\n})();\n\n<\/script>\n\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":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_header_footer","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"footnotes":""},"class_list":["post-10532","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/letsrideportugal.com\/es\/wp-json\/wp\/v2\/pages\/10532","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/letsrideportugal.com\/es\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/letsrideportugal.com\/es\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/letsrideportugal.com\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/letsrideportugal.com\/es\/wp-json\/wp\/v2\/comments?post=10532"}],"version-history":[{"count":3,"href":"https:\/\/letsrideportugal.com\/es\/wp-json\/wp\/v2\/pages\/10532\/revisions"}],"predecessor-version":[{"id":10891,"href":"https:\/\/letsrideportugal.com\/es\/wp-json\/wp\/v2\/pages\/10532\/revisions\/10891"}],"wp:attachment":[{"href":"https:\/\/letsrideportugal.com\/es\/wp-json\/wp\/v2\/media?parent=10532"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}