Kathedrale von Palma, Hochaltar. Ein Werk von Gaudí.
Reserva tu mesa en Qanat
Selecciona fecha, hora y número de comensales
Selecciona una fecha para ver los horarios disponibles
Reserva y puntualidad
Mantendremos tu mesa reservada durante 15 minutos de cortesía. Si prevés llegar más tarde, te agradeceremos que nos lo comuniques. En caso contrario, no podremos garantizar la disponibilidad de la reserva.
Cancelaciones
Las cancelaciones realizadas con menos de 24 horas de antelación no serán reembolsables en ningún caso.
Edad mínima
El acceso está permitido únicamente a mayores de 14 años.
Mascotas
Las mascotas son bienvenidas en nuestra terraza, siempre que permanezcan limpias, tranquilas, atadas y bajo la supervisión de su responsable, evitando en todo momento molestias al resto de los clientes. Nos reservamos el derecho de asignar la mesa que consideremos más adecuada. Durante la temporada de invierno, te rogamos que nos consultes antes de realizar la reserva.
Código de vestimenta
Agradecemos una vestimenta smart casual: elegante, cómoda e informal.
Convivencia
Te rogamos mantener un ambiente tranquilo, evitando alzar la voz y mostrando respeto tanto hacia los demás clientes como hacia nuestro equipo. Está permitido fumar únicamente en la zona habilitada para ello.
Restricciones alimentarias
Si tienes alguna alergia, intolerancia o restricción alimentaria, te agradeceremos que nos lo comuniques antes de tu llegada. Una vez iniciado el servicio, no podemos garantizar que sea posible realizar modificaciones en el menú.
Con el fin de preservar el ambiente y el bienestar de todos los presentes, nos reservamos el derecho de solicitar el abandono del establecimiento en caso de comportamientos que alteren la convivencia o el normal desarrollo del servicio.
Procesando...
' + flavorI18n.loadingTimes + '
'; fetch(flavorRestUrl + 'restaurants/' + flavorRestaurantId + '/available-slots?date=' + dateStr + '&guests=' + guests) .then(function(r) { return r.json(); }) .then(function(data) { if (data.success && data.data && data.data.length > 0) { var html = ''; data.data.forEach(function(slot) { var timeShort = slot.time.substring(0, 5); if (slot.available) { var cls = 'flavor-slot' + (flavorData.time === timeShort ? ' on' : ''); html += ''; } else { var reasonText = flavorI18n.notAvailable; if (slot.reason === 'capacity') reasonText = flavorI18n.capacityFull; else if (slot.reason === 'max_reservations') reasonText = flavorI18n.maxReservations; else if (slot.reason === 'min_advance') reasonText = flavorI18n.minAdvance; html += ''; } }); container.innerHTML = html; container.querySelectorAll('.flavor-slot:not(.busy)').forEach(function(b) { b.addEventListener('click', function() { flavorData.time = b.dataset.t; container.querySelectorAll('.flavor-slot').forEach(function(s) { s.classList.remove('on'); }); b.classList.add('on'); flavorCheckStep1(); }); }); } else { container.innerHTML = '' + flavorI18n.noTimesAvailable + '
'; } }) .catch(function() { container.innerHTML = '' + flavorI18n.errorLoadingTimes + '
'; }); } // ===================== // CHIPS (Guests) // ===================== document.getElementById('flavorChips').addEventListener('click', function(e) { var c = e.target.closest('.flavor-chip'); if (!c) return; flavorData.guests = parseInt(c.dataset.val); document.querySelectorAll('.flavor-chip').forEach(function(x) { x.classList.remove('on'); }); c.classList.add('on'); if (flavorData.date) { flavorData.time = null; flavorLoadTimeSlots(flavorData.date); } flavorCheckStep1(); }); // ===================== // SHARED TABLE TOGGLE // ===================== var sharedToggle = document.getElementById('flavorSharedToggle'); if (sharedToggle) { sharedToggle.addEventListener('click', function() { flavorData.shared = !flavorData.shared; sharedToggle.classList.toggle('on', flavorData.shared); }); } // ===================== // VALIDATIONS // ===================== function flavorCheckStep1() { var hasBooking = !!(flavorData.date && flavorData.time); if (flavorTotalSteps === 2) { // In 2-step mode, step 1 also contains data fields var hasData = ['flavor-first-name','flavor-last-name','flavor-email','flavor-phone'].every(function(id) { return document.getElementById(id).value.trim() !== ''; }); document.getElementById('flavorBtn1Next').disabled = !(hasBooking && hasData); } else { document.getElementById('flavorBtn1Next').disabled = !hasBooking; } } function flavorCheckStep2() { var ok = ['flavor-first-name','flavor-last-name','flavor-email','flavor-phone'].every(function(id) { return document.getElementById(id).value.trim() !== ''; }); var btn2 = document.getElementById('flavorBtn2Next'); if (btn2) btn2.disabled = !ok; } function flavorCheckStep3() { var chk = document.getElementById('flavor-accept-terms'); // El checkbox solo existe si procede; si no está, el botón queda disponible document.getElementById('flavorBtn3Confirm').disabled = chk ? !chk.checked : false; } ['flavor-first-name','flavor-last-name','flavor-email','flavor-phone'].forEach(function(id) { document.getElementById(id).addEventListener('input', function() { flavorCheckStep2(); if (flavorTotalSteps === 2) flavorCheckStep1(); }); }); (function(){ var chk = document.getElementById('flavor-accept-terms'); if (chk) chk.addEventListener('change', flavorCheckStep3); })(); function flavorValidateStep2() { var fn = document.getElementById('flavor-first-name').value.trim(); var ln = document.getElementById('flavor-last-name').value.trim(); var em = document.getElementById('flavor-email').value.trim(); var ph = document.getElementById('flavor-phone').value.trim(); if (!fn) { flavorToast(flavorI18n.nameRequired); return false; } if (!ln) { flavorToast(flavorI18n.lastNameRequired); return false; } if (!em) { flavorToast(flavorI18n.emailRequired); return false; } if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(em)) { flavorToast(flavorI18n.emailInvalid); return false; } if (!ph) { flavorToast(flavorI18n.phoneRequired); return false; } return true; } // ===================== // SUMMARY // ===================== function flavorBuildSummary() { document.getElementById('sumGuests').textContent = flavorData.guests + ' ' + (flavorData.guests === 1 ? flavorI18n.person : flavorI18n.people); if (flavorData.date) { var parts = flavorData.date.split('-'); var d = new Date(parseInt(parts[0]), parseInt(parts[1]) - 1, parseInt(parts[2])); var dn = flavorI18n.dayNames[d.getDay()].toLowerCase(); document.getElementById('sumDate').textContent = dn + ', ' + parseInt(parts[2]) + ' de ' + flavorI18n.months[parseInt(parts[1]) - 1].toLowerCase() + ' ' + parts[0]; } document.getElementById('sumTime').textContent = flavorData.time ? flavorData.time + 'h' : '\u2014'; var fn = document.getElementById('flavor-first-name').value.trim(); var ln = document.getElementById('flavor-last-name').value.trim(); document.getElementById('sumName').textContent = (fn + ' ' + ln).trim() || '\u2014'; document.getElementById('sumEmail').textContent = document.getElementById('flavor-email').value.trim() || '\u2014'; var pre = document.getElementById('flavor-prefix').value; var ph = document.getElementById('flavor-phone').value.trim(); document.getElementById('sumPhone').textContent = ph ? pre + ph : '\u2014'; document.getElementById('sumShared').textContent = flavorData.shared ? flavorI18n.yes : flavorI18n.no; document.getElementById('sumNotes').textContent = document.getElementById('flavor-notes').value.trim() || '\u2014'; var depositAmount = flavorCalculateDeposit(); var depositBox = document.getElementById('flavorDepositBox'); var cardBox = document.getElementById('flavorCardInputBox'); if (depositAmount > 0 && flavorStripeKey) { depositBox.style.display = 'block'; cardBox.style.display = 'block'; document.getElementById('flavorDepAmount').textContent = depositAmount.toFixed(2) + ' \u20AC'; var perPerson = flavorDepositPerPerson > 0 ? (flavorData.guests + ' \u00D7 ' + flavorDepositPerPerson.toFixed(2) + ' \u20AC ' + flavorI18n.perPerson) : ''; document.getElementById('flavorDepSub').textContent = perPerson; document.getElementById('flavor-submit-text').style.display = 'none'; document.getElementById('flavor-submit-text-pay').style.display = 'inline'; } else { depositBox.style.display = 'none'; cardBox.style.display = 'none'; document.getElementById('flavor-submit-text').style.display = 'inline'; document.getElementById('flavor-submit-text-pay').style.display = 'none'; } } // ===================== // NAVIGATION BUTTONS // ===================== document.getElementById('flavorBtn1Next').addEventListener('click', function() { if (!flavorData.guests) { flavorToast(flavorI18n.selectGuests); return; } if (!flavorData.date) { flavorToast(flavorI18n.selectDate); return; } if (!flavorData.time) { flavorToast(flavorI18n.selectTime); return; } if (flavorTotalSteps === 2 && !flavorValidateStep2()) return; flavorGoStep(2); }); var btn2Back = document.getElementById('flavorBtn2Back'); if (btn2Back) btn2Back.addEventListener('click', function() { flavorGoStep(1); }); var btn2Next = document.getElementById('flavorBtn2Next'); if (btn2Next) btn2Next.addEventListener('click', function() { if (!flavorValidateStep2()) return; flavorGoStep(3); }); document.getElementById('flavorBtn3Back').addEventListener('click', function() { flavorGoStep(flavorTotalSteps === 2 ? 1 : 2); }); document.getElementById('flavorBtn3Confirm').addEventListener('click', function() { flavorSubmit(); }); // Stepper click document.querySelectorAll('.flavor-step-ind').forEach(function(el) { el.addEventListener('click', function() { var target = parseInt(el.dataset.step); if (target < flavorStep) flavorGoStep(target); }); }); // ===================== // DEPOSIT & STRIPE // ===================== function flavorCalculateDeposit() { if (!flavorRequireDeposit) return 0; return flavorDepositPerReservation + (flavorDepositPerPerson * (flavorData.guests || 0)); } function flavorInitStripe() { var depositAmount = flavorCalculateDeposit(); if (depositAmount > 0 && flavorStripeKey && !flavorStripe) { flavorStripe = Stripe(flavorStripeKey); var elements = flavorStripe.elements({locale: 'es'}); flavorCardElement = elements.create('card', { style: { base: { fontSize: '14px', color: '#1a1a1a', fontFamily: 'Inter, -apple-system, sans-serif', '::placeholder': { color: '#c0c0c0' } }, invalid: { color: '#dc2626' } } }); flavorCardElement.mount('#flavor-card-element'); flavorCardElement.on('change', function(event) { document.getElementById('flavor-card-errors').textContent = event.error ? event.error.message : ''; }); } } // ===================== // SUBMIT // ===================== function flavorSubmit() { var _chk = document.getElementById('flavor-accept-terms'); if (_chk && !_chk.checked) { flavorToast(flavorI18n.acceptTerms); return; } // In 2-step mode, validate step2 fields before submit if (flavorTotalSteps === 2 && !flavorValidateStep2()) return; var depositAmount = flavorCalculateDeposit(); if (depositAmount > 0 && flavorStripeKey && flavorCardElement) { flavorSubmitWithPayment(); } else { flavorSubmitWithoutPayment(); } } function flavorGetPostData() { var prefix = document.getElementById('flavor-prefix').value; var phone = document.getElementById('flavor-phone').value.trim(); return { restaurant_id: flavorRestaurantId, shortcode_key: flavorShortcodeKey, guests: flavorData.guests, reservation_date: flavorData.date, reservation_time: flavorData.time, first_name: document.getElementById('flavor-first-name').value, last_name: document.getElementById('flavor-last-name').value, email: document.getElementById('flavor-email').value, phone: prefix + phone, allergies: document.getElementById('flavor-allergies').value, dietary_restrictions: '', notes: document.getElementById('flavor-notes').value, shared_table: flavorData.shared ? 1 : 0 }; } function flavorSubmitWithoutPayment() { document.querySelector('.flavor-loader').style.display = 'flex'; fetch(flavorRestUrl + 'reservations', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(flavorGetPostData()) }) .then(function(r) { return r.json(); }) .then(function(r) { document.querySelector('.flavor-loader').style.display = 'none'; if (r.success) { flavorShowSuccess(r.reservation.reservation || r.reservation); } else { flavorShowError(r.message || 'Error al crear la reserva'); } }) .catch(function() { document.querySelector('.flavor-loader').style.display = 'none'; flavorShowError(flavorI18n.error); }); } function flavorSubmitWithPayment() { var submitBtn = document.getElementById('flavorBtn3Confirm'); submitBtn.disabled = true; submitBtn.innerHTML = '' + flavorI18n.paymentProcessing + ''; var postData = flavorGetPostData(); var customerName = postData.first_name + ' ' + postData.last_name; var customerEmail = postData.email; fetch(flavorRestUrl + 'payment/create-intent', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ restaurant_id: flavorRestaurantId, guests: flavorData.guests, name: customerName, email: customerEmail }) }) .then(function(resp) { return resp.json(); }) .then(function(paymentData) { if (!paymentData.success) throw new Error(paymentData.message || 'Error al iniciar el pago'); return flavorStripe.confirmCardPayment(paymentData.data.client_secret, { payment_method: { card: flavorCardElement, billing_details: { name: customerName, email: customerEmail } } }).then(function(result) { if (result.error) throw new Error(result.error.message); return result.paymentIntent.id; }); }) .then(function(paymentIntentId) { postData.payment_intent_id = paymentIntentId; postData.deposit_paid = 1; return fetch(flavorRestUrl + 'reservations', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(postData) }); }) .then(function(response) { return response.json(); }) .then(function(r) { if (!r.success) throw new Error(r.message || 'Error al crear la reserva'); submitBtn.disabled = false; flavorShowSuccess(r.reservation.reservation || r.reservation); }) .catch(function(error) { submitBtn.disabled = false; submitBtn.innerHTML = '' + flavorI18n.paymentProcessing + ''; document.getElementById('flavor-card-errors').textContent = error.message; flavorToast(error.message); }); } // ===================== // SUCCESS / ERROR // ===================== // Ejecuta un snippet de tracking pegado por el restaurante desde el backoffice. // El snippet se sirve como' + flavorI18n.reservationSuccess + '
' + '' + flavorI18n.receiveEmail + '
' + '' + '' + message + '
' + '' + 'Entdecke Pollença, Wiege der Kunst und Spiritualität auf Mallorca: Kirchen, der Kalvarienberg, künstlerische Tradition und…
Entdecke die Wintergastronomie auf Mallorca: Saisongerichte, traditionelle Rezepte und das neue Ernte-Olivenöl, das jeden Bissen…
Finca Raixa – ein ikonisches Anwesen am Fuße der Sierra de Tramuntana auf Mallorca mit…
Alles, was Sie über den Flughafen Mallorca wissen müssen: Lage, Anreise, Terminal, Services und praktische…
Holzofen, Tonschüssel und langsames Feuer: die drei Säulen der traditionellen mallorquinischen Küche. Geschichte, Techniken, Rezept…
Finca Treurer auf Mallorca verwandelt Alperujo in Kompost, nutzt Wasser und Solarenergie wieder – ein…