bodhitree

Enlightened Solutions

Where technology meets human understanding


Current Projects

Explore Kindred

Meaningful human connection,
through inner change

Stamford Orchard

Local honey, lovingly tended bees

(() => { function initialiseProjects() { const root = document.getElementById("bt-project-carousel"); if (!root || root.dataset.ready) return; const scope = document.getElementById("home-section") || document; const normalise = value => value.replace(/\s+/g, " ").trim(); function linkedWordmark(hostname) { for (const link of scope.querySelectorAll("a[href]")) { let url; try { url = new URL(link.getAttribute("href"), location.href); } catch { continue; } if (url.hostname !== hostname) continue; const component = link.closest( ".image-component, .text-component" ); if ( component && !root.contains(component) && component.nextElementSibling && component.nextElementSibling.matches(".text-component") ) { return component; } } return null; } const kindred = linkedWordmark("kindred.tribestardust.com"); const orchard = linkedWordmark("stamfordorchard.com"); if (!kindred || !orchard || kindred === orchard) { console.warn( "Project carousel: check both linked wordmarks and their descriptions." ); return; } const kindredDescription = kindred.nextElementSibling; const orchardDescription = orchard.nextElementSibling; const orchardText = normalise(orchardDescription.textContent) .replace(/\.$/, "") .trim(); if ( !normalise(kindredDescription.textContent).startsWith( "Meaningful human connection" ) || orchardText !== "Local honey, lovingly tended bees" ) { console.warn( "Project carousel: each description must directly follow its wordmark." ); return; } /* * Read the Orchard text component's Carrd colour before moving it. * Its link will inherit this colour instead of a separate link colour. */ if (orchard.matches(".text-component")) { root.style.setProperty( "--bt-orchard-wordmark-colour", getComputedStyle(orchard).color ); } const projects = [ { name: "Kindred", logo: kindred, description: kindredDescription }, { name: "Stamford Orchard", logo: orchard, description: orchardDescription } ]; /* Preserve Carrd font families before moving the elements. */ const fontFamilies = []; projects.forEach(project => { [project.logo, project.description].forEach(component => { if (!component.matches(".text-component")) return; [component, ...component.querySelectorAll("*")].forEach(element => { fontFamilies.push({ element, family: getComputedStyle(element).fontFamily }); }); }); }); fontFamilies.forEach(({ element, family }) => { element.style.setProperty("font-family", family, "important"); }); root.dataset.ready = "true"; const track = root.querySelector(".bt-project-track"); const stage = root.querySelector(".bt-project-window"); const dots = Array.from(root.querySelectorAll(".bt-project-dot")); const toggle = root.querySelector(".bt-project-toggle"); const status = root.querySelector(".bt-project-status"); kindred.before(root); const panels = projects.map((project, projectIndex) => { const panel = document.createElement("div"); panel.className = "bt-project-panel " + (projectIndex === 0 ? "bt-project-kindred" : "bt-project-orchard"); panel.setAttribute("role", "group"); panel.setAttribute("aria-roledescription", "slide"); panel.setAttribute( "aria-label", `${projectIndex + 1} of ${projects.length}: ${project.name}` ); const logoSlot = document.createElement("div"); logoSlot.className = "bt-project-logo-slot"; logoSlot.append(project.logo); panel.append(logoSlot, project.description); track.append(panel); panel.querySelectorAll("img").forEach(img => { img.draggable = false; }); return panel; }); const reducedMotion = matchMedia("(prefers-reduced-motion: reduce)"); const hoverCapability = matchMedia("(hover: hover)"); let index = 0; let timer = 0; let paused = reducedMotion.matches; let hovered = false; let focused = false; let visible = false; let touching = false; let touchStart = null; let suppressClickUntil = 0; function updateToggle() { toggle.setAttribute( "aria-label", paused ? "Start automatic project rotation" : "Pause automatic project rotation" ); toggle.querySelector("span").textContent = paused ? "▷" : "Ⅱ"; } function scheduleRotation() { clearTimeout(timer); if ( paused || hovered || focused || touching || !visible || document.hidden ) { return; } timer = setTimeout(() => { showProject(index + 1, false); }, 11000); } function showProject(next, manual) { index = (next + projects.length) % projects.length; track.style.transform = `translateX(-${index * 100}%)`; panels.forEach((panel, panelIndex) => { const active = panelIndex === index; panel.inert = !active; panel.setAttribute("aria-hidden", String(!active)); dots[panelIndex].setAttribute("aria-current", String(active)); }); if (manual) { status.textContent = `${projects[index].name}, project ${index + 1} of ${projects.length}`; } scheduleRotation(); } root.querySelector(".bt-project-prev").addEventListener("click", () => { showProject(index - 1, true); }); root.querySelector(".bt-project-next").addEventListener("click", () => { showProject(index + 1, true); }); dots.forEach((dot, dotIndex) => { dot.addEventListener("click", () => { showProject(dotIndex, true); }); }); toggle.addEventListener("click", () => { paused = !paused; updateToggle(); scheduleRotation(); }); root.addEventListener("mouseenter", () => { if (!hoverCapability.matches) return; hovered = true; scheduleRotation(); }); root.addEventListener("mouseleave", () => { hovered = false; scheduleRotation(); }); root.addEventListener("focusin", () => { focused = true; scheduleRotation(); }); root.addEventListener("focusout", () => { requestAnimationFrame(() => { focused = root.contains(document.activeElement); scheduleRotation(); }); }); root.addEventListener("keydown", event => { if ( event.key !== "ArrowLeft" && event.key !== "ArrowRight" ) { return; } event.preventDefault(); const next = index + (event.key === "ArrowRight" ? 1 : -1); const nextIndex = (next + projects.length) % projects.length; dots[nextIndex].focus(); showProject(next, true); }); stage.addEventListener("touchstart", event => { if (event.touches.length !== 1) { touchStart = null; return; } touching = true; touchStart = { x: event.touches[0].clientX, y: event.touches[0].clientY }; scheduleRotation(); }, { passive: true }); stage.addEventListener("touchend", event => { touching = false; if (touchStart && event.changedTouches.length) { const touch = event.changedTouches[0]; const dx = touch.clientX - touchStart.x; const dy = touch.clientY - touchStart.y; if ( Math.abs(dx) > 45 && Math.abs(dx) > Math.abs(dy) * 1.2 ) { suppressClickUntil = Date.now() + 500; showProject(index + (dx < 0 ? 1 : -1), true); } } touchStart = null; scheduleRotation(); }, { passive: true }); stage.addEventListener("touchcancel", () => { touching = false; touchStart = null; scheduleRotation(); }, { passive: true }); stage.addEventListener("click", event => { if (Date.now() < suppressClickUntil) { event.preventDefault(); event.stopPropagation(); } }, true); document.addEventListener("visibilitychange", scheduleRotation); reducedMotion.addEventListener("change", event => { if (event.matches) { paused = true; updateToggle(); scheduleRotation(); } }); root.hidden = false; updateToggle(); showProject(0, false); if ("IntersectionObserver" in window) { new IntersectionObserver(entries => { visible = entries[0].isIntersecting; scheduleRotation(); }, { threshold: 0.25 }).observe(root); } else { visible = true; scheduleRotation(); } } if (document.readyState === "loading") { document.addEventListener( "DOMContentLoaded", initialiseProjects, { once: true } ); } else { initialiseProjects(); } })();

Where technology meets
human understanding

bo·dhi tree (bō′dē)

The sacred fig tree at Bodh Gaya, India, beneath which, according to Buddhist tradition, Siddhartha Gautama attained enlightenment and became the Buddha.Bodhi (बोधि), a Sanskrit and Pāli word, is traditionally translated into English as ‘enlightenment’, although its literal meaning is closer to ‘awakening’. In Buddhism, it refers to insight into the true nature of things. It derives from the root budh, meaning to awaken or to understand.

the meaning behind bodhitree

For me, bodhitree represents curiosity, reflection and the possibility of seeing things more clearly. The name reminds me to stay open, to question what I know and to look beyond familiar ways of thinking.

Science, Technology and Spirituality

These have long been interests of mine, alongside a deep appreciation for the natural world. I AM drawn to questions about the mind, the nature of reality and the human condition, and am fascinated by the parallels between ancient philosophy and contemporary science.Through bodhitree, I bring these interests together. It reflects my desire to explore how technology can support understanding, meaningful connection and a more conscious way of living.

(() => { const apiKey = "AIzaSyCxwpIipp4jnoAPxE1MO6ZM0hJTKsSOjYQ"; /* Existing map coordinates; entrance accuracy remains unconfirmed. */ const location = { lat: 52.649389, lng: -0.489722 }; const element = document.getElementById("bodhitree-map"); const wrap = document.getElementById("bodhitree-map-wrap"); const pin = document.getElementById("bodhitree-map-pin"); const panel = document.getElementById("bodhitree-map-directions"); const destination = encodeURIComponent( `${location.lat},${location.lng}` ); document.getElementById("bodhitree-directions-apple").href = "https://maps.apple.com/?daddr=" + destination + "&dirflg=d"; document.getElementById("bodhitree-directions-google").href = "https://www.google.com/maps/dir/?api=1&destination=" + destination + "&travelmode=driving"; document.getElementById("bodhitree-directions-waze").href = "https://www.waze.com/ul?ll=" + destination + "&navigate=yes"; function closeDirections(returnFocus = false) { panel.hidden = true; pin.setAttribute("aria-expanded", "false"); if (returnFocus) pin.focus(); } pin.addEventListener("click", () => { const opening = panel.hidden; panel.hidden = !opening; pin.setAttribute("aria-expanded", String(opening)); }); document.addEventListener("click", event => { if ( !pin.contains(event.target) && !panel.contains(event.target) ) { closeDirections(); } }); document.addEventListener("keydown", event => { if (event.key === "Escape" && !panel.hidden) { closeDirections(true); } }); wrap.addEventListener("focusout", event => { if (!wrap.contains(event.relatedTarget)) { closeDirections(); } }); window.addEventListener("hashchange", () => { closeDirections(); }); let started = false; window.initBodhitreeMap = function () { const map = new google.maps.Map(element, { center: location, zoom: 13, mapTypeId: "roadmap", disableDefaultUI: true, gestureHandling: "none", keyboardShortcuts: false, clickableIcons: false, backgroundColor: "#202020", styles: [ { elementType: "geometry", stylers: [{ color: "#202020" }] }, { elementType: "labels", stylers: [{ visibility: "off" }] }, { featureType: "landscape", elementType: "geometry", stylers: [{ color: "#202020" }] }, { featureType: "road", elementType: "geometry", stylers: [ { visibility: "on" }, { color: "#414141" }, { weight: 1 } ] }, { featureType: "road", elementType: "geometry", stylers: [ { visibility: "simplified" }, { color: "#3b3b3b" }, { weight: 1 } ] }, { featureType: "road", elementType: "geometry.stroke", stylers: [ { color: "#202020" }, { weight: 0 } ] }, { featureType: "water", elementType: "geometry", stylers: [{ color: "#111111" }] }, { featureType: "administrative", elementType: "geometry", stylers: [{ color: "#151515" }] }, { featureType: "poi", stylers: [{ visibility: "off" }] }, { featureType: "transit", stylers: [{ visibility: "off" }] } ] }); new ResizeObserver(() => { if (element.clientWidth && element.clientHeight) { google.maps.event.trigger(map, "resize"); map.setCenter(location); } }).observe(element); }; const observer = new IntersectionObserver(entries => { if ( started || !entries.some(entry => entry.isIntersecting) ) { return; } started = true; observer.disconnect(); if (window.google && window.google.maps) { window.initBodhitreeMap(); return; } const script = document.createElement("script"); script.src = "https://maps.googleapis.com/maps/api/js?key=" + encodeURIComponent(apiKey) + "&loading=async&callback=initBodhitreeMap&v=weekly"; script.async = true; document.head.appendChild(script); }); observer.observe(element); })();