Add feature animations and update styles for kiosks and about pages

- Introduced `featuresAnim` option in editor and index files to enable feature ticker animations.
- Updated rendering logic to include feature animations in the about section.
- Added new JavaScript files for handling animations on the about page and kiosks page.
- Adjusted CSS classes to accommodate new animations and ensure proper visual representation.
- Changed primary color in theme defaults for a more cohesive design.
This commit is contained in:
Matt Batchelder
2026-04-09 11:06:17 -04:00
parent 6f16a698f5
commit 942f02a1c1
11 changed files with 685 additions and 28 deletions

View File

@@ -0,0 +1,64 @@
/**
* About Page Animator
* Cycles an is-active highlight through feature rows in .features-stage.
* Respects prefers-reduced-motion and pauses via IntersectionObserver.
* Mirrors the patterns and conventions of solutions-animator.js.
*/
(function () {
'use strict';
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
var CYCLE_MS = 2000;
function initFeatures(stage) {
var items = stage.querySelectorAll('.feat-item');
if (!items.length) return;
var state = { idx: 0, timer: null };
function advance() {
items[state.idx].classList.remove('is-active');
state.idx = (state.idx + 1) % items.length;
items[state.idx].classList.add('is-active');
}
function startTimer() {
if (state.timer) return;
state.timer = setInterval(advance, CYCLE_MS);
}
function stopTimer() {
clearInterval(state.timer);
state.timer = null;
}
items[0].classList.add('is-active');
if ('IntersectionObserver' in window) {
new IntersectionObserver(function (entries) {
for (var i = 0; i < entries.length; i++) {
entries[i].isIntersecting ? startTimer() : stopTimer();
}
}, { rootMargin: '200px', threshold: 0.05 }).observe(stage);
} else {
startTimer();
}
}
function boot() {
var stages = document.querySelectorAll('.features-stage');
if (!stages.length) return;
for (var i = 0; i < stages.length; i++) {
if (stages[i]._featAnim) continue;
stages[i]._featAnim = true;
initFeatures(stages[i]);
}
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', boot);
} else {
boot();
}
})();