(() => {
const IGNORE = new Set([
'Capa_2','MapaCR','Regiones','Mapa_Base','SombraMapa','Base','Contorno'
]);
// Si un ID/target no está mapeado, generamos /regiones/<slug>/
const autoUrl = { enabled: true, baseUrl: '/coffee-region/' };
const linkMap = {
// 'norte': '/regiones/norte/',
// 'perez_zeledon': '/regiones/perez-zeledon/',
};
// Utils
const slug = s => String(s)
.normalize('NFD').replace(/[\u0300-\u036f]/g,'')
.toLowerCase().replace(/[^a-z0-9]+/g,'-').replace(/(^-|-$)/g,'');
const toKey = s => String(s)
.normalize('NFD').replace(/[\u0300-\u036f]/g,'')
.toLowerCase().replace(/[^a-z0-9]+/g,'_').replace(/(^_|_$)/g,'');
const urlFor = key =>
linkMap[key] || (autoUrl.enabled ? `${autoUrl.baseUrl.replace(/\/$/,'')}/${slug(key)}/` : null);
// Región "hoja": tiene geometría y no anida otros [id] distintos de sí
const isLeafRegion = (el) => {
const hasGeom = el.matches('path,polygon,polyline,rect,circle,ellipse') ||
el.querySelector('path,polygon,polyline,rect,circle,ellipse');
if (!hasGeom) return false;
const innerWithId = el.querySelectorAll('[id]');
if (innerWithId.length === 0) return true;
if (innerWithId.length === 1 && innerWithId[0] === el) return true;
return true; // grupos con geometría sin otros ids también cuentan
};
// Llevar el nodo al tope visual (z-order)
const bringToFront = (el) => {
const svg = el.ownerSVGElement;
if (svg && el.parentNode) el.parentNode.appendChild(el);
};
// Hover sync región ↔ bloques
const setHover = (regionEl, blockEls, on) => {
regionEl.classList.toggle('is-hover', !!on);
blockEls.forEach(b => b.classList.toggle('is-hover', !!on));
if (on) bringToFront(regionEl);
};
const makeRegionInteractive = (regionEl, key, url, blockEls) => {
regionEl.classList.add('cr-region');
regionEl.setAttribute('tabindex','0');
regionEl.setAttribute('role','link');
regionEl.setAttribute('aria-label', key.replace(/[_-]/g,' '));
const go = (e) => {
e.preventDefault();
if (!url) return;
if (e.metaKey || e.ctrlKey) window.open(url, '_blank');
else window.location.href = url;
};
const over = () => setHover(regionEl, blockEls, true);
const out = () => setHover(regionEl, blockEls, false);
regionEl.addEventListener('click', go);
regionEl.addEventListener('keydown', e => {
if (e.key === 'Enter' || e.key === ' ') go(e);
});
regionEl.addEventListener('mousedown', e => e.preventDefault());
regionEl.addEventListener('mouseenter', over);
regionEl.addEventListener('mouseleave', out);
regionEl.addEventListener('focus', over, true);
regionEl.addEventListener('blur', out, true);
regionEl.addEventListener('touchstart', over, { passive: true });
document.addEventListener('touchend', out, { passive: true });
};
const makeBlockInteractive = (blockEl, key, url, regionEl) => {
// Asegura rol/tabindex en el bloque (aunque ya lo tengas en Bricks)
blockEl.setAttribute('role','button');
blockEl.setAttribute('tabindex','0');
blockEl.setAttribute('aria-label', (blockEl.getAttribute('aria-label') || key).replace(/[_-]/g,' '));
const go = (e) => {
// Evita navegar si el click vino de un <a>
if (e.target.closest('a')) return;
e.preventDefault();
if (!url) return;
if (e.metaKey || e.ctrlKey) window.open(url, '_blank');
else window.location.href = url;
};
const over = () => setHover(regionEl, [blockEl], true);
const out = () => setHover(regionEl, [blockEl], false);
blockEl.addEventListener('click', go);
blockEl.addEventListener('keydown', e => {
if (e.key === 'Enter' || e.key === ' ') go(e);
});
blockEl.addEventListener('mouseenter', over);
blockEl.addEventListener('mouseleave', out);
blockEl.addEventListener('focus', over, true);
blockEl.addEventListener('blur', out, true);
blockEl.addEventListener('touchstart', over, { passive: true });
document.addEventListener('touchend', out, { passive: true });
};
const activate = (svg) => {
// Limpia clases previas
svg.querySelectorAll('.cr-region').forEach(n => n.classList.remove('cr-region','is-hover'));
const root = svg.querySelector('#MapaCR') || svg;
// Candidatos con id (excluye contenedores)
const candidates = [...root.querySelectorAll('[id]')].filter(n => !IGNORE.has(n.id));
// Solo “hojas” con geometría
const leaves = candidates.filter(isLeafRegion);
// Mapa clave → región
const regions = [];
leaves.forEach(el => {
const id = el.id;
if (!id) return;
const key = toKey(id);
// Bloques que apuntan al mismo key
const blockEls = [...document.querySelectorAll(`.region-link[data-target="${key}"]`)];
if (blockEls.length === 0) return; // si no hay bloque, no enlazamos
const url = urlFor(key);
regions.push({ el, key, url, blocks: blockEls });
});
// Activa interactividad en ambos lados
regions.forEach(({ el, key, url, blocks }) => {
makeRegionInteractive(el, key, url, blocks);
blocks.forEach(b => makeBlockInteractive(b, key, url, el));
});
};
const boot = () => {
const svg = document.querySelector('svg');
if (svg) activate(svg);
};
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', boot);
} else {
boot();
}
})();
Coffee Regions
Discover the regions, producers, and regenerative practices behind our specialty coffees — where quality, soil health, and long-term resilience come together.
Where Climate, Soil and Culture Meet
Our coffee regions are defined not only by climate and geography, but by the way coffee is grown. Across diverse landscapes, our partner producers apply regenerative practices that restore soil health, strengthen biodiversity, and support resilient farming systems — creating the conditions for consistently high-quality specialty coffee over time.
Learn More About Regenerative Coffee
Costa Rica’s Coffee Regions
Each region tells a different story — where regenerative practices meet specialty coffee.
(() => {
const IGNORE = new Set([
'Capa_2','MapaCR','Regiones','Mapa_Base','SombraMapa','Base','Contorno'
]);
// Si un ID/target no está mapeado, generamos /regiones/<slug>/
const autoUrl = { enabled: true, baseUrl: '/coffee-region/' };
const linkMap = {
// 'norte': '/regiones/norte/',
// 'perez_zeledon': '/regiones/perez-zeledon/',
};
// Utils
const slug = s => String(s)
.normalize('NFD').replace(/[\u0300-\u036f]/g,'')
.toLowerCase().replace(/[^a-z0-9]+/g,'-').replace(/(^-|-$)/g,'');
const toKey = s => String(s)
.normalize('NFD').replace(/[\u0300-\u036f]/g,'')
.toLowerCase().replace(/[^a-z0-9]+/g,'_').replace(/(^_|_$)/g,'');
const urlFor = key =>
linkMap[key] || (autoUrl.enabled ? `${autoUrl.baseUrl.replace(/\/$/,'')}/${slug(key)}/` : null);
// Región "hoja": tiene geometría y no anida otros [id] distintos de sí
const isLeafRegion = (el) => {
const hasGeom = el.matches('path,polygon,polyline,rect,circle,ellipse') ||
el.querySelector('path,polygon,polyline,rect,circle,ellipse');
if (!hasGeom) return false;
const innerWithId = el.querySelectorAll('[id]');
if (innerWithId.length === 0) return true;
if (innerWithId.length === 1 && innerWithId[0] === el) return true;
return true; // grupos con geometría sin otros ids también cuentan
};
// Llevar el nodo al tope visual (z-order)
const bringToFront = (el) => {
const svg = el.ownerSVGElement;
if (svg && el.parentNode) el.parentNode.appendChild(el);
};
// Hover sync región ↔ bloques
const setHover = (regionEl, blockEls, on) => {
regionEl.classList.toggle('is-hover', !!on);
blockEls.forEach(b => b.classList.toggle('is-hover', !!on));
if (on) bringToFront(regionEl);
};
const makeRegionInteractive = (regionEl, key, url, blockEls) => {
regionEl.classList.add('cr-region');
regionEl.setAttribute('tabindex','0');
regionEl.setAttribute('role','link');
regionEl.setAttribute('aria-label', key.replace(/[_-]/g,' '));
const go = (e) => {
e.preventDefault();
if (!url) return;
if (e.metaKey || e.ctrlKey) window.open(url, '_blank');
else window.location.href = url;
};
const over = () => setHover(regionEl, blockEls, true);
const out = () => setHover(regionEl, blockEls, false);
regionEl.addEventListener('click', go);
regionEl.addEventListener('keydown', e => {
if (e.key === 'Enter' || e.key === ' ') go(e);
});
regionEl.addEventListener('mousedown', e => e.preventDefault());
regionEl.addEventListener('mouseenter', over);
regionEl.addEventListener('mouseleave', out);
regionEl.addEventListener('focus', over, true);
regionEl.addEventListener('blur', out, true);
regionEl.addEventListener('touchstart', over, { passive: true });
document.addEventListener('touchend', out, { passive: true });
};
const makeBlockInteractive = (blockEl, key, url, regionEl) => {
// Asegura rol/tabindex en el bloque (aunque ya lo tengas en Bricks)
blockEl.setAttribute('role','button');
blockEl.setAttribute('tabindex','0');
blockEl.setAttribute('aria-label', (blockEl.getAttribute('aria-label') || key).replace(/[_-]/g,' '));
const go = (e) => {
// Evita navegar si el click vino de un <a>
if (e.target.closest('a')) return;
e.preventDefault();
if (!url) return;
if (e.metaKey || e.ctrlKey) window.open(url, '_blank');
else window.location.href = url;
};
const over = () => setHover(regionEl, [blockEl], true);
const out = () => setHover(regionEl, [blockEl], false);
blockEl.addEventListener('click', go);
blockEl.addEventListener('keydown', e => {
if (e.key === 'Enter' || e.key === ' ') go(e);
});
blockEl.addEventListener('mouseenter', over);
blockEl.addEventListener('mouseleave', out);
blockEl.addEventListener('focus', over, true);
blockEl.addEventListener('blur', out, true);
blockEl.addEventListener('touchstart', over, { passive: true });
document.addEventListener('touchend', out, { passive: true });
};
const activate = (svg) => {
// Limpia clases previas
svg.querySelectorAll('.cr-region').forEach(n => n.classList.remove('cr-region','is-hover'));
const root = svg.querySelector('#MapaCR') || svg;
// Candidatos con id (excluye contenedores)
const candidates = [...root.querySelectorAll('[id]')].filter(n => !IGNORE.has(n.id));
// Solo “hojas” con geometría
const leaves = candidates.filter(isLeafRegion);
// Mapa clave → región
const regions = [];
leaves.forEach(el => {
const id = el.id;
if (!id) return;
const key = toKey(id);
// Bloques que apuntan al mismo key
const blockEls = [...document.querySelectorAll(`.region-link[data-target="${key}"]`)];
if (blockEls.length === 0) return; // si no hay bloque, no enlazamos
const url = urlFor(key);
regions.push({ el, key, url, blocks: blockEls });
});
// Activa interactividad en ambos lados
regions.forEach(({ el, key, url, blocks }) => {
makeRegionInteractive(el, key, url, blocks);
blocks.forEach(b => makeBlockInteractive(b, key, url, el));
});
};
const boot = () => {
const svg = document.querySelector('svg');
if (svg) activate(svg);
};
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', boot);
} else {
boot();
}
})();

North Region

West Valley

Central Valley

Turrialba

Los Santos

Pérez Zeledón

Coto Brus
Meet Our Growers
Behind every bag of Buena Vida coffee are farmers committed to regeneration, community, and excellence.
Meet All Our Growers
From Soil to Cup
From cultivation to roasting, every step in Buena Vida’s coffee process respects nature’s rhythms.

Cultivation

Harvesting

Procesing












