Free
Call to action
Crumbelle Call to action
A call to action block extracted from the Crumbelle template, available in Tailwind CSS and Bootstrap.
0
2
A call to action block extracted from the Crumbelle template, available in Tailwind CSS and Bootstrap.
<!DOCTYPE html>
<html lang="en">
<head>
<script>
window.FontAwesomeConfig = { autoReplaceSvg: 'nest' };
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/js/all.min.js" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Crumbelle Call to action | Tailwind CSS UI Block</title>
<meta name="description" content="A call to action block extracted from the Crumbelle template, available in Tailwind CSS and Bootstrap.">
<meta name="keywords" content="Crumbelle, Tailwind CSS template, HTML website template, bakery template, pastry shop website, dessert delivery, cake shop, food and restaurant template, online bakery">
<meta name="author" content="Let's templates">
<link rel="canonical" href="">
<meta property="og:type" content="product">
<meta property="og:site_name" content="Let's templates">
<meta property="og:locale" content="en_US">
<meta property="og:url" content="">
<meta property="og:title" content="Crumbelle | Tailwind CSS Food & Restaurant Template">
<meta property="og:description" content="A cheerful, checkerboard Tailwind CSS bakery template with product boxes, a build-your-box configurator and a delivery checker.">
<meta property="og:image" content="">
<meta property="og:image:alt" content="Crumbelle template preview">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:url" content="">
<meta name="twitter:title" content="Crumbelle | Tailwind CSS Food & Restaurant Template">
<meta name="twitter:description" content="A cheerful, checkerboard Tailwind CSS bakery template with product boxes, a build-your-box configurator and a delivery checker.">
<meta name="twitter:image" content="">
<meta name="twitter:image:alt" content="Crumbelle template preview">
<script src="https://cdn.tailwindcss.com/3.4.17"></script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Chewy&family=Poppins:wght@400;500;600&display=swap" rel="stylesheet">
<script>
tailwind.config = {
theme: {
extend: {
colors: { blush: '#fdecec', rose: { DEFAULT: '#f7a6a8', deep: '#ef7f86' }, mint: '#b2dcc7', pistachio: '#e1e8c4', peach: '#fcd2b4', ink: '#141414' },
fontFamily: { sans: ['Poppins', 'sans-serif'], display: ['Chewy', 'cursive'] }
}
}
}
</script>
<style>
@view-transition { navigation: auto; }
::view-transition-old(root) { animation: 180ms ease-out both page-fade-out; }
::view-transition-new(root) { animation: 220ms ease-in both page-fade-in; }
@keyframes page-fade-out { to { opacity: 0; } }
@keyframes page-fade-in { from { opacity: 0; } }
html { scroll-behavior: smooth; }
[hidden] { display: none !important; }
.checker { background-color: #e1e8c4; background-image: conic-gradient(#d3e6c6 25%, transparent 0 50%, #d3e6c6 0 75%, transparent 0); background-size: 3.5rem 3.5rem; }
.checker-mint { background-color: #c6e4d2; background-image: conic-gradient(#e6efcf 25%, transparent 0 50%, #e6efcf 0 75%, transparent 0); background-size: 3.5rem 3.5rem; }
.btn-pop { box-shadow: 0 3px 0 #141414; transition: transform .15s, box-shadow .15s; }
.btn-pop:hover { transform: translateY(-2px); box-shadow: 0 5px 0 #141414; }
.btn-pop:active { transform: translateY(2px); box-shadow: 0 1px 0 #141414; }
.wave-top { clip-path: polygon(0 18%, 8% 12%, 20% 6%, 35% 4%, 50% 7%, 62% 11%, 72% 9%, 84% 4%, 93% 6%, 100% 10%, 100% 100%, 0 100%); }
.wiggle:hover { animation: wiggle .5s ease-in-out; }
@keyframes wiggle { 25% { transform: rotate(-3deg); } 75% { transform: rotate(3deg); } }
.reveal-ready [data-reveal] { opacity: 0; transform: translateY(24px); transition: opacity .6s ease, transform .6s ease; transition-delay: var(--reveal-delay, 0ms); }
.reveal-ready [data-reveal].is-visible { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
html { scroll-behavior: auto; }
.wiggle:hover { animation: none; }
::view-transition-old(root), ::view-transition-new(root) { animation: none; }
}
</style>
</head>
<body class="bg-blush font-sans text-ink antialiased">
<% active_page = "index" %>
<% main_nav = { "about" => "About us", "pastries" => "Pastries", "contact" => "Contact" } %>
<% more_nav = { "delivery" => "Delivery", "order" => "Build a box" } %>
<% main_nav.each do |slug, label| %>
<% active = active_page == slug %>
<% end %>
<% more_nav.each do |slug, label| %>
<% end %>
<% { "index" => "Home" }.merge(main_nav).merge(more_nav).merge("login" => "Login").each do |slug, label| %>
<% active = active_page == slug %>
<% end %>
<% products = [
["Butter croissant", "Box of 6", "$18", "1555507036-ab1f4038808a", "Two golden croissants dusted with sugar"],
["Fudge brownie", "Box of 9", "$16", "1606313564200-e75d5e30476c", "Stack of fudgy chocolate brownies"],
["Cinnamon roll", "Box of 6", "$20", "1509365465985-25d11c17e812", "Cinnamon rolls dusted with sugar on a dark tray"],
["Lemon meringue tart", "Whole tart", "$24", "1519915028121-7d3463d20b13", "Lemon tart topped with toasted meringue"],
["Cherry lattice pie", "Two mini pies", "$15", "1464305795204-6f5bbfc7fb81", "Two cherry lattice pies with fresh berries"],
["Confetti cupcakes", "Box of 4", "$17", "1519869325930-281384150729", "Vanilla cupcakes with swirled frosting and sprinkles"]
] %>
<% products.each_with_index do |(name, size, price, photo, alt), index| %>
<% end %>
<% [["fa-fire-burner", "Bake", "Every pastry leaves the oven golden and still warm.", "bg-rose"], ["fa-box-open", "Pack", "We box them gently so nothing arrives squashed.", "bg-mint"], ["fa-truck-fast", "Ship", "Your treats turn up quickly, fresh and ready to enjoy.", "bg-pistachio"]].each_with_index do |(icon, title, text, tone), index| %>
<% end %>
<% promises = [["fa-egg", "Butter, flour, eggs. That's the list", "Plus salt and patience. Nothing else goes in."], ["fa-rotate-left", "Fresh, or your money back", "If it isn't perfect when it lands, we refund you. No questions."], ["fa-truck", "Baked today, sent today", "Out of the oven at dawn and on its way by lunch."], ["fa-ban", "No mystery ingredients", "No preservatives, no fillers, just good baking done right."]] %>
<% left, right = promises.each_slice(2).to_a %>
<% [left, nil, right].each do |group| %>
<% if group %>
<% group.each do |icon, title, text| %>
<% end %>
<% else %>
<% end %>
<% end %>
<% quotes = [["They taste like they came from the corner bakery, not a delivery box.", "Sofia Lindqvist", "Regular customer", 2], ["Quick delivery, and the croissants were still warm when the box opened.", "Daniel Mensah", "Breakfast lover", 3], ["Finally a bakery I can trust. Short ingredient lists, brilliant baking.", "Aiko Tanaka", "Home baker", 4]] %>
<% quotes.each_with_index do |(quote, name, role, avatar), index| %>
<% 5.times do %>
<% end %>
<% end %>
<% [["Two-day delivery almost everywhere", "Order in the morning, enjoy fresh pastries by the next afternoon.", "1526367790999-0150786686a2", "Courier cycling a delivery bag down a narrow street", "bg-pistachio", "delivery"], ["Packaging that's kind to the planet", "Our boxes are fully compostable, because good baking shouldn't cost the earth.", "1530610476181-d83430b64dcd", "Fresh croissants piled on a café counter", "bg-mint", "about"], ["Subscribe and save on every box", "A fresh box every week at a price that actually makes sense.", "1556910103-1c02745aae4d", "Couple cooking together in a home kitchen", "bg-peach", "order"]].each do |title, text, photo, alt, tone, href| %>
<% end %>
<% faqs = [["How fresh is everything?", "Everything is baked the morning it ships. Nothing is made days ahead, so you get it at its best, usually within 24 hours of baking."], ["How long does delivery take?", "Most orders arrive in two to three working days in insulated packaging, and every order comes with tracking."], ["Do you bake gluten-free?", "Not yet, though we're testing recipes. For now everything contains wheat flour, and we're careful about cross-contamination."], ["What if my box arrives damaged?", "Tell us within 24 hours and we'll replace it or refund you. We pack with care, and we stand behind every box."], ["Can I pause or cancel a subscription?", "Any time, with no penalty. Pause or cancel from your account page whenever you like."]] %>
<% faqs.each_with_index do |(question, answer), index| %>
<% end %>
<!-- block:start cta -->
<section class="grid md:grid-cols-2">
<div class="checker flex flex-col justify-center px-5 py-16 md:px-12 lg:px-[max(3rem,calc((100vw-72rem)/2+2rem))]">
<h2 class="font-display text-5xl leading-tight md:text-6xl">Hungry for something fresh?</h2>
<p class="mt-5 max-w-md text-lg">Order today and taste the difference real baking makes.</p>
<div class="mt-8 flex gap-3">
<a href="order.html" class="btn-pop rounded-md border border-ink bg-rose px-6 py-2.5 font-medium">Order</a>
<a href="pastries.html" class="btn-pop rounded-md border border-ink bg-white px-6 py-2.5 font-medium">Learn</a>
</div>
</div>
<img src="https://images.unsplash.com/photo-1495147466023-ac5c588e2e94?auto=format&fit=crop&w=1200&q=80" alt="Rows of small fruit tarts topped with berries and kiwi" class="aspect-[4/3] h-full w-full object-cover md:aspect-auto" loading="lazy">
</section>
<!-- block:end cta -->
<script>
document.querySelectorAll('[data-menu-toggle]').forEach((button) => {
const menu = document.getElementById(button.getAttribute('aria-controls'));
if (!menu) return;
button.addEventListener('click', () => {
const open = button.getAttribute('aria-expanded') === 'true';
button.setAttribute('aria-expanded', String(!open));
menu.classList.toggle('hidden', open);
});
});
document.querySelectorAll('[data-dropdown]').forEach((dropdown) => {
const toggle = dropdown.querySelector('[data-dropdown-toggle]');
const menu = document.getElementById(toggle.getAttribute('aria-controls'));
const set = (open) => { toggle.setAttribute('aria-expanded', String(open)); menu.classList.toggle('hidden', !open); };
toggle.addEventListener('click', () => set(toggle.getAttribute('aria-expanded') !== 'true'));
document.addEventListener('click', (event) => { if (!dropdown.contains(event.target)) set(false); });
dropdown.addEventListener('keydown', (event) => { if (event.key === 'Escape') { set(false); toggle.focus(); } });
});
document.querySelectorAll('[data-accordion]').forEach((accordion) => {
accordion.querySelectorAll('[data-accordion-trigger]').forEach((trigger) => {
const panel = document.getElementById(trigger.getAttribute('aria-controls'));
const icon = () => trigger.querySelector('svg') || trigger.querySelector('i');
const sync = () => { const open = trigger.getAttribute('aria-expanded') === 'true'; panel.hidden = !open; icon()?.classList.toggle('rotate-180', open); };
trigger.addEventListener('click', () => { trigger.setAttribute('aria-expanded', String(trigger.getAttribute('aria-expanded') !== 'true')); sync(); });
sync();
});
});
document.querySelectorAll('[data-tabs]').forEach((tablist) => {
const tabs = [...tablist.querySelectorAll('[role="tab"]')];
const select = (tab) => tabs.forEach((other) => {
const active = other === tab;
other.setAttribute('aria-selected', String(active));
other.tabIndex = active ? 0 : -1;
document.getElementById(other.getAttribute('aria-controls')).hidden = !active;
});
tabs.forEach((tab, index) => {
tab.addEventListener('click', () => select(tab));
tab.addEventListener('keydown', (event) => {
const step = { ArrowRight: 1, ArrowDown: 1, ArrowLeft: -1, ArrowUp: -1 }[event.key];
if (!step) return;
event.preventDefault();
const next = tabs[(index + step + tabs.length) % tabs.length];
next.focus();
select(next);
});
});
});
document.querySelectorAll('[data-box-builder]').forEach((builder) => {
const size = Number(builder.dataset.boxSize);
const summary = builder.querySelector('[data-box-summary]');
const count = builder.querySelector('[data-box-count]');
const total = builder.querySelector('[data-box-total]');
const bar = builder.querySelector('[data-box-bar]');
const submit = builder.querySelector('[data-box-submit]');
const slots = [...builder.querySelectorAll('[data-box-slot]')];
const update = () => {
const items = [...builder.querySelectorAll('[data-box-item]')];
let pieces = 0;
let price = 0;
const fill = [];
items.forEach((item) => {
const qty = Number(item.querySelector('[data-qty]').textContent);
pieces += qty;
price += qty * Number(item.dataset.price);
for (let i = 0; i < qty; i += 1) fill.push(item.dataset.emoji);
item.querySelector('[data-step="-1"]').disabled = qty === 0;
});
items.forEach((item) => { item.querySelector('[data-step="1"]').disabled = pieces >= size; });
slots.forEach((slot, i) => { slot.textContent = fill[i] || ''; slot.classList.toggle('is-filled', Boolean(fill[i])); });
count.textContent = pieces;
total.textContent = price.toFixed(2);
bar.style.width = `${(pieces / size) * 100}%`;
summary.textContent = pieces === size ? 'Your box is full. Ready when you are!' : `Add ${size - pieces} more to fill your box.`;
submit.disabled = pieces !== size;
};
builder.addEventListener('click', (event) => {
const button = event.target.closest('[data-step]');
if (!button) return;
const qty = button.closest('[data-box-item]').querySelector('[data-qty]');
qty.textContent = Math.max(0, Number(qty.textContent) + Number(button.dataset.step));
update();
});
builder.addEventListener('submit', (event) => {
event.preventDefault();
builder.querySelector('[data-form-status]').textContent = 'Lovely! Your box is saved. Pick a delivery day at checkout.';
});
update();
});
document.querySelectorAll('[data-postcode-check]').forEach((form) => {
const status = form.querySelector('[data-form-status]');
form.addEventListener('submit', (event) => {
event.preventDefault();
const value = String(form.querySelector('[name="postcode"]').value || '').trim().toUpperCase();
if (!value) { status.textContent = 'Type your postcode first.'; return; }
const area = value.replace(/[^A-Z]/g, '').slice(0, 2);
const local = ['BA', 'BS', 'SN', 'GL'].includes(area);
status.textContent = local ? `Good news: we deliver to ${value} the next day, Tuesday to Saturday.` : `We deliver to ${value} in two to three working days.`;
});
});
document.querySelectorAll('[data-flip]').forEach((card) => {
card.addEventListener('click', () => card.setAttribute('aria-pressed', String(card.getAttribute('aria-pressed') !== 'true')));
});
document.querySelectorAll('[data-contact-form]').forEach((form) => {
form.addEventListener('submit', (event) => {
event.preventDefault();
const status = form.querySelector('[data-form-status]');
if (!form.checkValidity()) {
status.textContent = form.dataset.error;
form.querySelector(':invalid')?.focus();
return;
}
status.textContent = form.dataset.success;
form.reset();
});
});
document.querySelectorAll('[data-current-year]').forEach((el) => { el.textContent = new Date().getFullYear(); });
(() => {
const items = document.querySelectorAll('[data-reveal]');
const skip = navigator.webdriver || !('IntersectionObserver' in window) || matchMedia('(prefers-reduced-motion: reduce)').matches;
if (!items.length || skip) return;
document.documentElement.classList.add('reveal-ready');
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (!entry.isIntersecting) return;
entry.target.classList.add('is-visible');
observer.unobserve(entry.target);
});
}, { rootMargin: '0px 0px -10% 0px' });
items.forEach((item) => observer.observe(item));
})();
</script>
</body>
</html>
Food & Restaurant
Unlock the entire library of premium templates and blocks. Renews automatically, cancel anytime.
Tailwind CSS · HTML download