Add Astra child theme for Hop On Hop Off header & footer
- disables Astra header/footer via astra_header/astra_footer hooks and renders custom design markup (logo, nav dropdown, footer columns, socials, support) - chrome.css scoped to .hoho (generated from the design source); chrome.js for burger/submenu/sticky/back-to-top; bundled icon sprite (reuses plugin's) - parameterize scope-css.js scope via VC_SCOPE env Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J4hNL1PSHxXbu94SCenpKj
This commit is contained in:
74
astra-child-hoponhopoff/assets/chrome.js
Normal file
74
astra-child-hoponhopoff/assets/chrome.js
Normal file
@@ -0,0 +1,74 @@
|
||||
/* Hop On Hop Off — header/footer interactions (child theme).
|
||||
Ported from the mockup's main.js: burger menu, Tours submenu, sticky header
|
||||
over a hero (solid otherwise), and the footer "back to top" button. */
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
var header = document.getElementById("siteHeader");
|
||||
var nav = document.getElementById("primaryNav");
|
||||
var burger = document.getElementById("burger");
|
||||
var navToggle = nav && nav.querySelector(".nav__toggle");
|
||||
var mqDesktop = window.matchMedia("(min-width: 60.0625rem)");
|
||||
|
||||
/* ---------- mobile menu ---------- */
|
||||
function closeMenu() {
|
||||
if (!nav || !burger) return;
|
||||
nav.classList.remove("is-open");
|
||||
burger.setAttribute("aria-expanded", "false");
|
||||
}
|
||||
|
||||
if (burger && nav) {
|
||||
burger.addEventListener("click", function () {
|
||||
var open = nav.classList.toggle("is-open");
|
||||
burger.setAttribute("aria-expanded", String(open));
|
||||
});
|
||||
document.addEventListener("click", function (e) {
|
||||
if (mqDesktop.matches) return;
|
||||
if (!nav.contains(e.target) && !burger.contains(e.target)) closeMenu();
|
||||
});
|
||||
nav.addEventListener("click", function (e) {
|
||||
if (!mqDesktop.matches && e.target.closest("a")) closeMenu();
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener("keydown", function (e) {
|
||||
if (e.key !== "Escape") return;
|
||||
closeMenu();
|
||||
if (navToggle) navToggle.setAttribute("aria-expanded", "false");
|
||||
});
|
||||
mqDesktop.addEventListener("change", function (e) { if (e.matches) closeMenu(); });
|
||||
|
||||
/* ---------- Tours submenu ---------- */
|
||||
if (navToggle) {
|
||||
navToggle.addEventListener("click", function () {
|
||||
var open = navToggle.getAttribute("aria-expanded") === "true";
|
||||
navToggle.setAttribute("aria-expanded", String(!open));
|
||||
});
|
||||
}
|
||||
|
||||
/* ---------- header: sticky over a hero, solid elsewhere ---------- */
|
||||
var hero = document.querySelector(".hero, .hero-tour, .hero--archive");
|
||||
if (header) {
|
||||
if (hero && "IntersectionObserver" in window) {
|
||||
var sentinel = document.createElement("div");
|
||||
sentinel.setAttribute("aria-hidden", "true");
|
||||
sentinel.style.cssText = "position:absolute;top:0;left:0;width:1px;height:60vh;pointer-events:none";
|
||||
hero.appendChild(sentinel);
|
||||
new IntersectionObserver(function (entries) {
|
||||
header.classList.toggle("is-stuck", !entries[0].isIntersecting);
|
||||
}, { threshold: 0 }).observe(sentinel);
|
||||
} else {
|
||||
/* No hero to overlay — show a readable solid header from the start. */
|
||||
header.classList.add("is-solid");
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------- footer: back to top ---------- */
|
||||
var toTop = document.querySelector(".ring-badge--top");
|
||||
if (toTop) {
|
||||
toTop.addEventListener("click", function (e) {
|
||||
e.preventDefault();
|
||||
window.scrollTo({ top: 0, behavior: "smooth" });
|
||||
});
|
||||
}
|
||||
})();
|
||||
Reference in New Issue
Block a user