/* ---- assets/js/events.js ---- */ window.AGP_EVENTS = [ { date: "2025-06-20", endDate: "2025-06-22", title: "Monty Roberts — The Movement 2025", venue: "Flag Is Up Farms", location: "Solvang, CA, USA", mode: "in-person", detail: "The 8th annual multi-day event focusing on Equus, mindfulness, and non-violent communication.", link: "/contact/", image: "assets/img/event-movement2025.jpg" }, { date: "2025-11-10", endDate: "", title: "Monty Roberts Advance Course", venue: "MRILC – Monty Roberts International Learning Center", location: "Solvang, CA, USA", mode: "in-person", detail: "Ruler education, lecture and live demonstration.", link: "/contact/", image: "assets/img/event-old.jpg" }, { date: "2026-01-01", endDate: "", title: "Rose Parade", venue: "", location: "Pasadena, CA, USA", mode: "in-person", detail: "OVERSEES ALL TRACTION DEVICES ON ALL 200 PARADE HORSES FOR THE 7 MILES OF PAVEMENT", link: "/contact/", image: "assets/img/event-old.jpg" }, { date: "2026-04-05", endDate: "", title: "Monty Roberts Advance Course", venue: "MRILC – Monty Roberts International Learning Center", location: "Solvang, CA, USA", mode: "in-person", detail: "Ruler education, lecture and live demonstration.", link: "/contact/", image: "assets/img/event-old.jpg" }, { date: "2026-10-23", endDate: "", title: "Foundations Clinic with Ada Gates Patton", venue: "Brier Equestrian & Wellness Centre", location: "Fenwick, Nova Scotia, Canada", mode: "in-person", detail: "A hands-on 1-day clinic featuring a live trimming demonstration and lecture on achieving anatomically balanced hooves - open to farriers, veterinarians, and all equestrians.", link: "/contact/", image: "assets/img/event-briar.jpg" }, { date: "2026-11-01", endDate: "", title: "Thoroughbred Sale", venue: "Keeneland Sales Pavilion", location: "Lexington, KY, USA", mode: "in-person", detail: "Ada will be advising buyers on conformation of prospective purchases for breeding.", link: "/contact/", image: "assets/img/event-keeneland.jpg" }, { date: "2026-11-15", endDate: "", title: "Monty Roberts Advance Course – Date to Be Confirmed (November 2026)", venue: "MRILC – Monty Roberts International Learning Center", location: "Solvang, CA, USA", mode: "in-person", detail: "Ruler education, lecture and live demonstration. Exact date and location coming soon — check back or subscribe to the calendar for updates.", link: "/contact/", image: "assets/img/event-roberts.jpg" }, { date: "2027-01-01", endDate: "", title: "Rose Parade", venue: "", location: "Pasadena, CA, USA", mode: "in-person", detail: "OVERSEES ALL TRACTION DEVICES ON ALL 200 PARADE HORSES FOR THE 7 MILES OF PAVEMENT", link: "/contact/", image: "assets/img/event-parade.jpg" }, { date: "2027-04-15", endDate: "", title: "Monty Roberts Advance Course – Date to Be Confirmed (April 2027)", venue: "MRILC – Monty Roberts International Learning Center", location: "Solvang, CA, USA", mode: "in-person", detail: "Ruler education, lecture and live demonstration. Exact date and location coming soon — check back or subscribe to the calendar for updates.", link: "/contact/", image: "assets/img/event-roberts.jpg" } ]; /* ---- assets/js/main.js ---- */ (function () { 'use strict'; var reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches; var header = document.querySelector('.site-header'); if (header) { var onScroll = function () { header.classList.toggle('is-stuck', window.scrollY > 40); }; onScroll(); window.addEventListener('scroll', onScroll, { passive: true }); } if (header) { var navH = function () { var stuck = header.classList.contains('is-stuck'); if (stuck) header.classList.remove('is-stuck'); var h = header.getBoundingClientRect().height; if (stuck) header.classList.add('is-stuck'); document.documentElement.style.setProperty('--nav-h', h.toFixed(2) + 'px'); }; navH(); window.addEventListener('resize', navH); if (document.fonts && document.fonts.ready) document.fonts.ready.then(navH); } var heroBrand = document.querySelector('.hero__brand'); var heroHeadline = document.querySelector('.hero__headline'); var heroContent = document.querySelector('.hero__content'); if (heroBrand && heroHeadline && heroContent && header) { var placeBrand = function () { if (getComputedStyle(heroBrand).position === 'static') { heroBrand.style.removeProperty('--brand-top'); return; } var navBottom = header.getBoundingClientRect().bottom; var headTop = heroHeadline.getBoundingClientRect().top; var brandH = heroBrand.getBoundingClientRect().height; var midpoint = navBottom + (headTop - navBottom) / 2; var offset = midpoint - brandH / 2 - heroContent.getBoundingClientRect().top; heroBrand.style.setProperty('--brand-top', offset.toFixed(1) + 'px'); }; placeBrand(); window.addEventListener('resize', placeBrand); if (document.fonts && document.fonts.ready) document.fonts.ready.then(placeBrand); } var toggle = document.querySelector('.nav-toggle'); var overlay = document.querySelector('.nav-overlay'); if (toggle && overlay) { var setMenu = function (open) { toggle.setAttribute('aria-expanded', String(open)); overlay.classList.toggle('is-open', open); document.body.classList.toggle('is-locked', open); overlay.setAttribute('aria-hidden', String(!open)); if (open) { var first = overlay.querySelector('a'); if (first) first.focus(); } }; toggle.addEventListener('click', function () { setMenu(toggle.getAttribute('aria-expanded') !== 'true'); }); overlay.addEventListener('click', function (e) { if (e.target.tagName === 'A') setMenu(false); }); document.addEventListener('keydown', function (e) { if (e.key === 'Escape' && toggle.getAttribute('aria-expanded') === 'true') { setMenu(false); toggle.focus(); } }); } var groups = document.querySelectorAll('.nav-group'); Array.prototype.forEach.call(groups, function (group) { var btn = group.querySelector('button'); if (!btn) return; var open = function (state) { group.setAttribute('data-open', String(state)); btn.setAttribute('aria-expanded', String(state)); }; btn.addEventListener('click', function (e) { e.stopPropagation(); open(group.getAttribute('data-open') !== 'true'); }); group.addEventListener('mouseenter', function () { open(true); }); group.addEventListener('mouseleave', function () { open(false); }); group.addEventListener('focusout', function (e) { if (!group.contains(e.relatedTarget)) open(false); }); document.addEventListener('click', function () { open(false); }); document.addEventListener('keydown', function (e) { if (e.key === 'Escape') open(false); }); }); var revealables = document.querySelectorAll('[data-reveal]'); if (reduceMotion || !('IntersectionObserver' in window)) { Array.prototype.forEach.call(revealables, function (el) { el.classList.add('is-in'); }); } else { var io = new IntersectionObserver(function (entries) { entries.forEach(function (entry) { if (entry.isIntersecting) { entry.target.classList.add('is-in'); io.unobserve(entry.target); } }); }, { rootMargin: '0px 0px -8% 0px', threshold: 0.08 }); Array.prototype.forEach.call(revealables, function (el) { io.observe(el); }); } var accButtons = document.querySelectorAll('.acc-btn'); Array.prototype.forEach.call(accButtons, function (btn) { var item = btn.closest('.acc-item'); var panel = item && item.querySelector('.acc-panel'); if (!item || !panel) return; btn.setAttribute('aria-expanded', item.getAttribute('data-open') === 'true' ? 'true' : 'false'); btn.addEventListener('click', function () { var willOpen = item.getAttribute('data-open') !== 'true'; var group = item.parentElement; Array.prototype.forEach.call(group.querySelectorAll('.acc-item'), function (sib) { sib.setAttribute('data-open', 'false'); var sibBtn = sib.querySelector('.acc-btn'); if (sibBtn) sibBtn.setAttribute('aria-expanded', 'false'); }); item.setAttribute('data-open', String(willOpen)); btn.setAttribute('aria-expanded', String(willOpen)); }); }); var trigger = document.getElementById('inquiry-nature'); if (trigger) { var paths = document.querySelectorAll('[data-path]'); var service = document.getElementById('service-requested'); var facility = document.querySelector('[data-conditional="facility"]'); var applyFacility = function () { if (!facility || !service) return; var v = service.value; facility.hidden = !(v === 'Clinics' || v === 'Audits'); }; var applyPaths = function () { var value = trigger.value; Array.prototype.forEach.call(paths, function (path) { var match = path.getAttribute('data-path') === value; path.hidden = !match; Array.prototype.forEach.call(path.querySelectorAll('input,select,textarea'), function (f) { f.disabled = !match; }); }); applyFacility(); }; trigger.addEventListener('change', applyPaths); if (service) service.addEventListener('change', applyFacility); applyPaths(); } var MONTHS = ['January','February','March','April','May','June', 'July','August','September','October','November','December']; function parseDay(iso) { var p = String(iso).split('-'); return new Date(+p[0], (+p[1] || 1) - 1, +p[2] || 1); } function formatRange(ev) { var s = parseDay(ev.date); var label = MONTHS[s.getMonth()] + ' ' + s.getDate(); if (ev.endDate) { var e = parseDay(ev.endDate); label += (e.getMonth() === s.getMonth() ? '–' + e.getDate() : ' – ' + MONTHS[e.getMonth()] + ' ' + e.getDate()); } return label + ', ' + s.getFullYear(); } function eventNode(ev, isPast) { var tag = document.createElement(ev.link ? 'a' : 'div'); tag.className = 'event-line' + (isPast ? ' is-past' : ''); if (ev.link) tag.href = ev.link; var date = document.createElement('span'); date.className = 'event-line__date'; date.textContent = formatRange(ev); var mid = document.createElement('span'); var title = document.createElement('h3'); title.className = 'event-line__title'; title.textContent = ev.title; mid.appendChild(title); if (ev.detail) { var detail = document.createElement('p'); detail.className = 'row-item__body event-detail'; detail.textContent = ev.detail; mid.appendChild(detail); } var place = document.createElement('span'); place.className = 'event-line__place'; if (ev.venue) { var venueLine = document.createElement('span'); venueLine.className = 'event-line__venue'; venueLine.textContent = ev.venue; place.appendChild(venueLine); } if (ev.location) { var locLine = document.createElement('span'); locLine.className = 'event-line__loc'; locLine.textContent = ev.location; place.appendChild(locLine); } var mode = document.createElement('span'); mode.className = 'event-line__tag'; mode.setAttribute('data-mode', ev.mode || 'in-person'); mode.textContent = ev.mode === 'online' ? 'Online' : 'In person'; tag.appendChild(date); tag.appendChild(mid); tag.appendChild(place); tag.appendChild(mode); return tag; } function renderEvents() { var data = (window.AGP_EVENTS || []).slice(); var today = new Date(); today.setHours(0, 0, 0, 0); data.sort(function (a, b) { return parseDay(a.date) - parseDay(b.date); }); var upcoming = data.filter(function (ev) { return parseDay(ev.endDate || ev.date) >= today; }); var past = data.filter(function (ev) { return parseDay(ev.endDate || ev.date) < today; }).reverse(); var band = document.querySelector('[data-events="band"]'); if (band) { var limit = parseInt(band.getAttribute('data-limit'), 10) || 3; if (!upcoming.length) { band.innerHTML = '

New dates are being confirmed. ' + 'Ask to be told first.

'; } else { upcoming.slice(0, limit).forEach(function (ev) { band.appendChild(eventNode(ev, false)); }); } } var list = document.querySelector('[data-events="upcoming"]'); if (list) { if (!upcoming.length) { list.innerHTML = '

No dates are on the books at this moment. ' + 'Inquire about hosting a clinic.

'; } else { upcoming.forEach(function (ev) { list.appendChild(eventNode(ev, false)); }); } list.classList.add('has-detail'); } var pastList = document.querySelector('[data-events="past"]'); if (pastList) { if (!past.length) { pastList.innerHTML = '

Past dates will collect here.

'; } else { past.forEach(function (ev) { pastList.appendChild(eventNode(ev, true)); }); } } var filters = document.querySelector('.cal-filters'); if (filters && list) { filters.addEventListener('click', function (e) { var btn = e.target.closest('button'); if (!btn) return; var want = btn.getAttribute('data-filter'); Array.prototype.forEach.call(filters.querySelectorAll('button'), function (b) { b.setAttribute('aria-pressed', String(b === btn)); }); Array.prototype.forEach.call(list.querySelectorAll('.event-line'), function (row) { var mode = row.querySelector('.event-line__tag').getAttribute('data-mode'); row.style.display = (want === 'all' || want === mode) ? '' : 'none'; }); }); } } if (document.querySelector('[data-events]')) renderEvents(); var detailHost = document.querySelector('.events--detailed'); if (detailHost) { var style = document.createElement('style'); style.textContent = '.events--detailed .event-detail{display:block;margin-top:.6rem;}' + '.events--detailed .event-line{align-items:start;}'; document.head.appendChild(style); } var archiveSearch = document.getElementById('archive-search'); if (archiveSearch) { var sections = [].slice.call(document.querySelectorAll('[data-archive-section]')); var cards = [].slice.call(document.querySelectorAll('[data-archive-item]')); var status = document.querySelector('.archive-search__status'); cards.forEach(function (card) { card.__haystack = (card.textContent || '').replace(/\s+/g, ' ').trim().toLowerCase(); }); var runFilter = function () { var q = archiveSearch.value.replace(/\s+/g, ' ').trim().toLowerCase(); var total = 0; sections.forEach(function (sec) { var shown = 0; [].forEach.call(sec.querySelectorAll('[data-archive-item]'), function (card) { var hit = !q || card.__haystack.indexOf(q) > -1; card.hidden = !hit; if (hit) shown++; }); sec.hidden = shown === 0; total += shown; }); if (!status) return; if (!q) status.textContent = ''; else if (total === 0) status.textContent = 'Nothing in the archive matches \u201c' + archiveSearch.value.trim() + '\u201d.'; else status.textContent = total + (total === 1 ? ' item' : ' items') + ' found.'; }; archiveSearch.addEventListener('input', runFilter); archiveSearch.addEventListener('search', runFilter); runFilter(); } [].forEach.call(document.querySelectorAll('.video-embed'), function (btn) { btn.addEventListener('click', function () { var id = btn.getAttribute('data-youtube'); if (!id || id.indexOf('REPLACE') === 0) return; var frame = document.createElement('iframe'); frame.src = 'https://www.youtube-nocookie.com/embed/' + encodeURIComponent(id) + '?autoplay=1&rel=0'; frame.title = btn.getAttribute('aria-label') || 'Video'; frame.allow = 'accelerometer; autoplay; clipboard-write; encrypted-media; picture-in-picture; web-share'; frame.setAttribute('allowfullscreen', ''); frame.setAttribute('referrerpolicy', 'strict-origin-when-cross-origin'); btn.innerHTML = ''; btn.appendChild(frame); btn.style.cursor = 'default'; }); }); var gallery = document.querySelector('[data-archive-gallery]'); if (gallery) { var box = document.createElement('div'); box.className = 'lightbox'; box.hidden = true; box.setAttribute('role', 'dialog'); box.setAttribute('aria-modal', 'true'); box.setAttribute('aria-label', 'Photo viewer'); box.innerHTML = '' + '' + '' + ''; document.body.appendChild(box); var lbImg = box.querySelector('img'); var lbCap = box.querySelector('.lightbox__caption'); var btnClose = box.querySelector('.lightbox__close'); var btnPrev = box.querySelector('.lightbox__nav--prev'); var btnNext = box.querySelector('.lightbox__nav--next'); var shots = [], at = 0, lastFocus = null; var visibleShots = function () { return [].filter.call(gallery.querySelectorAll('[data-lightbox]'), function (b) { var card = b.closest('[data-archive-item]'); return !(card && card.hidden); }); }; var show = function (i) { if (!shots.length) return; at = (i + shots.length) % shots.length; var btn = shots[at]; var img = btn.querySelector('img'); var card = btn.closest('[data-archive-item]'); var title = card ? card.querySelector('h3') : null; var meta = card ? card.querySelector('.meta') : null; lbImg.src = img.currentSrc || img.src; lbImg.alt = img.alt || ''; lbCap.innerHTML = (title ? '' + title.textContent.trim() + '' : '') + (meta ? '' + meta.textContent.trim() + '' : '') + '' + (at + 1) + ' of ' + shots.length + ''; var solo = shots.length < 2; btnPrev.hidden = solo; btnNext.hidden = solo; }; var open = function (btn) { shots = visibleShots(); var idx = shots.indexOf(btn); if (idx < 0) return; lastFocus = document.activeElement; box.hidden = false; document.body.classList.add('is-locked'); show(idx); requestAnimationFrame(function () { box.classList.add('is-open'); }); btnClose.focus(); }; var close = function () { box.classList.remove('is-open'); var done = function () { box.hidden = true; lbImg.removeAttribute('src'); document.body.classList.remove('is-locked'); if (lastFocus && lastFocus.focus) lastFocus.focus(); }; if (reduceMotion) done(); else setTimeout(done, 300); }; gallery.addEventListener('click', function (e) { var btn = e.target.closest('[data-lightbox]'); if (btn) { e.preventDefault(); open(btn); } }); btnClose.addEventListener('click', close); btnPrev.addEventListener('click', function () { show(at - 1); }); btnNext.addEventListener('click', function () { show(at + 1); }); box.addEventListener('click', function (e) { if (e.target === box || e.target.classList.contains('lightbox__stage')) close(); }); lbImg.addEventListener('error', function () { lbImg.alt = 'This photograph could not be loaded.'; }); document.addEventListener('keydown', function (e) { if (box.hidden) return; if (e.key === 'Escape') { e.preventDefault(); close(); } else if (e.key === 'ArrowLeft') { e.preventDefault(); show(at - 1); } else if (e.key === 'ArrowRight') { e.preventDefault(); show(at + 1); } else if (e.key === 'Tab') { var f = [btnClose, btnPrev, btnNext].filter(function (b) { return !b.hidden; }); var i = f.indexOf(document.activeElement); e.preventDefault(); f[(i + (e.shiftKey ? -1 : 1) + f.length) % f.length].focus(); } }); } Array.prototype.forEach.call(document.querySelectorAll('[data-year]'), function (el) { el.textContent = String(new Date().getFullYear()); }); })(); /* ---- ICS Calendar: reposition flyer image and make it clickable ---- */ (function () { function fixEvent(dd) { if (dd.hasAttribute('data-fixed')) return; var attach = dd.querySelector(':scope > .descloc > .attach'); if (!attach) return; dd.setAttribute('data-fixed', '1'); attach.parentNode.removeChild(attach); var info = document.createElement('div'); info.className = 'event-info'; while (dd.firstChild) { info.appendChild(dd.firstChild); } dd.appendChild(info); dd.appendChild(attach); var img = attach.querySelector('img'); if (img) { img.style.cursor = 'pointer'; var link = document.createElement('a'); link.href = img.src; link.target = '_blank'; link.rel = 'noopener'; img.parentNode.insertBefore(link, img); link.appendChild(img); } } function fixAll(root) { (root || document).querySelectorAll('.ics-calendar dd.event').forEach(fixEvent); } fixAll(); var icsObserver = new MutationObserver(function () { fixAll(); }); document.querySelectorAll('.r34ics-ajax-container').forEach(function (el) { icsObserver.observe(el, { childList: true, subtree: true }); }); })(); /* ---- Archive: pull video thumbnails directly from YouTube ---- */ (function () { document.querySelectorAll('.video-embed[data-youtube]').forEach(function (btn) { var id = btn.getAttribute('data-youtube'); if (!id || id.indexOf('REPLACE') === 0) return; var img = btn.querySelector('img'); if (!img) { img = document.createElement('img'); img.alt = btn.getAttribute('aria-label') || ''; btn.insertBefore(img, btn.firstChild); } img.src = 'https://img.youtube.com/vi/' + encodeURIComponent(id) + '/hqdefault.jpg'; }); })();