From 8feab03f002b964bb736dc022eceecc8ddc7473e Mon Sep 17 00:00:00 2001 From: amir Date: Tue, 15 Sep 2026 14:53:20 +0330 Subject: [PATCH] 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 Claude-Session: https://claude.ai/code/session_01J4hNL1PSHxXbu94SCenpKj --- astra-child-hoponhopoff/README.md | 84 + astra-child-hoponhopoff/assets/chrome.css | 3115 ++++++++++++++++++++ astra-child-hoponhopoff/assets/chrome.js | 74 + astra-child-hoponhopoff/assets/sprite.svg | 176 ++ astra-child-hoponhopoff/functions.php | 126 + astra-child-hoponhopoff/inc/footer.php | 88 + astra-child-hoponhopoff/inc/header.php | 51 + astra-child-hoponhopoff/inc/logo.php | 88 + astra-child-hoponhopoff/inc/nav-walker.php | 58 + astra-child-hoponhopoff/style.css | 12 + viator-collector/build/scope-css.js | 2 +- 11 files changed, 3873 insertions(+), 1 deletion(-) create mode 100644 astra-child-hoponhopoff/README.md create mode 100644 astra-child-hoponhopoff/assets/chrome.css create mode 100644 astra-child-hoponhopoff/assets/chrome.js create mode 100644 astra-child-hoponhopoff/assets/sprite.svg create mode 100644 astra-child-hoponhopoff/functions.php create mode 100644 astra-child-hoponhopoff/inc/footer.php create mode 100644 astra-child-hoponhopoff/inc/header.php create mode 100644 astra-child-hoponhopoff/inc/logo.php create mode 100644 astra-child-hoponhopoff/inc/nav-walker.php create mode 100644 astra-child-hoponhopoff/style.css diff --git a/astra-child-hoponhopoff/README.md b/astra-child-hoponhopoff/README.md new file mode 100644 index 0000000..fca0583 --- /dev/null +++ b/astra-child-hoponhopoff/README.md @@ -0,0 +1,84 @@ +# Hop On Hop Off — Astra Child Theme (header & footer) + +This child theme replaces **Astra's** default header and footer with the +"Hop On Hop Off" design (the same look as `new front/index.html`), while leaving +the rest of Astra untouched. It pairs with the **Viator Collector** plugin, which +styles the page content (listing / single / homepage sections). + +## What it does + +- Disables Astra's header/footer markup and renders custom ones via the + `astra_header` / `astra_footer` hooks. +- Loads the design CSS **scoped to `.hoho`** (`assets/chrome.css`) so it can't + collide with Astra or other plugins. +- Prints the SVG icon sprite site-wide (reusing the plugin's copy when active). +- Header nav is a real WordPress menu (with a Tours dropdown); footer columns, + logo, socials and copyright are dynamic. + +## Install (step by step) + +1. **Astra must be installed.** Appearance → Themes → make sure the *Astra* + parent theme is present (it can stay inactive; the child needs it as a base). +2. **Copy this folder** `astra-child-hoponhopoff/` into + `wp-content/themes/` on your site. +3. **Activate** it: Appearance → Themes → *Hop On Hop Off (Astra Child)* → Activate. +4. **Create the menus:** Appearance → Menus. Create and assign menus to these + locations (Manage Locations tab): + - **HoHo — Header Menu** → your top nav. To get the *Tours* dropdown, add a + top-level item named "Tours" and drag destination/tour links **underneath** + it (indented) as sub-items. + - **HoHo — Footer: Quick Access** + - **HoHo — Footer: Tours** + - **HoHo — Footer: User Account** + (Footer columns with no assigned menu simply render their heading only.) +5. **Logo (optional):** Appearance → Customize → Site Identity → Select Logo. + If none is set, the bundled "Hop On Hop Off" SVG wordmark is used. +6. **Social links (optional):** they default to `#`. Set real URLs with a snippet + in this theme's `functions.php`: + ```php + add_filter( 'hoho_socials', function ( $s ) { + $s['instagram'] = 'https://instagram.com/yourpage'; + $s['facebook'] = 'https://facebook.com/yourpage'; + $s['whatsapp'] = 'https://wa.me/…'; + $s['telegram'] = 'https://t.me/…'; + return $s; + } ); + ``` +7. **Footer blurb & support link (optional):** + ```php + add_filter( 'hoho_footer_about', fn() => 'Your footer paragraph.' ); + add_filter( 'hoho_support_url', fn() => 'https://example.com/contact' ); + ``` + +## Header behavior + +The header is **transparent and overlays a full-bleed hero** (homepage, and the +plugin's listing/single pages), then turns solid on scroll — exactly like the +mockup. On pages that have **no hero**, `chrome.js` adds `.is-solid`, so the +header renders as a solid, sticky bar that stays readable and doesn't cover +content. + +If on your site the transparent overlay ever sits wrong on a hero page (theme +wrappers differ between setups), force the solid style everywhere by changing the +top of `assets/chrome.js` so it always adds `is-solid`, or add this CSS: + +```css +.hoho .site-header { position: sticky; inset-block-start: 0; + background: rgba(0,0,0,.85); backdrop-filter: blur(12px); } +``` + +## Regenerating the CSS + +`assets/chrome.css` is generated from the design source with the plugin's scoper: + +```bash +VC_SCOPE=.hoho node ../viator-collector/build/scope-css.js "../new front/css/style.css" assets/chrome.css +``` + +## Notes + +- Requires the **Astra** parent theme. Tested against Astra's + `astra_header_markup` / `astra_footer_markup` hooks; if a future Astra version + renames those, update the `remove_action()` calls in `functions.php`. +- Icons come from `assets/sprite.svg` (``). When the Viator + Collector plugin is active, its identical sprite is reused to avoid duplication. diff --git a/astra-child-hoponhopoff/assets/chrome.css b/astra-child-hoponhopoff/assets/chrome.css new file mode 100644 index 0000000..078d88a --- /dev/null +++ b/astra-child-hoponhopoff/assets/chrome.css @@ -0,0 +1,3115 @@ +/* Generated by build/scope-css.js from new front/css/style.css — do not edit by hand. */ + +/* ========================================================= + Tokens + ========================================================= */ +:root { + --c-black: #000; + --c-white: #fff; + --c-accent: #fc0; + --c-teal: #2cafc2; + --c-teal-05: rgba(44, 175, 194, 0.05); + --c-green: #34c759; + --c-red: #ff383c; + --c-teal-20: rgba(44, 175, 194, 0.2); + --c-ink: #101317; + --c-muted: rgba(0, 0, 0, 0.5); + --c-line: rgba(0, 0, 0, 0.1); + --c-glass: rgba(0, 0, 0, 0.5); + + --r-pill: 2.5rem; + --r-card: 1.5rem; + --r-xl: 2rem; + + --fs-body: 1rem; + --fs-hero: clamp(2.25rem, 1.25rem + 4.4vw, 4rem); + --fs-h2: clamp(1.75rem, 1.15rem + 2.6vw, 2.5rem); + --fs-card: clamp(1.125rem, 0.95rem + 0.75vw, 1.5rem); + + --sp-1: 0.5rem; + --sp-2: 0.6875rem; + --sp-3: 1rem; + --sp-4: 1.5rem; + --sp-5: 2rem; + --sp-6: clamp(2.5rem, 1.5rem + 3.5vw, 5rem); + + --control-h: clamp(2.75rem, 2.4rem + 0.9vw, 3rem); + --container: 81rem; + --gutter: clamp(1rem, 0.4rem + 2.2vw, 3rem); + --page-inset: clamp(0.5rem, 0.2rem + 0.6vw, 0.75rem); + --header-h: calc(var(--control-h) + var(--sp-5)); + --gap: clamp(0.75rem, 0.4rem + 1vw, 1.5rem); + + --ease: cubic-bezier(0.4, 0, 0.2, 1); +} + +/* ========================================================= + Base + ========================================================= */ +.hoho *, +.hoho *::before, +.hoho *::after { + box-sizing: border-box; +} + +.hoho { + -webkit-text-size-adjust: 100%; + scroll-behavior: smooth; + overflow-x: hidden; +} + +.hoho { + margin: 0; + font-family: "Plus Jakarta Sans", system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; + font-size: var(--fs-body); + line-height: 1.5; + color: var(--c-ink); + background: var(--c-white); + overflow-x: hidden; +} + +.hoho img, +.hoho svg { + display: block; + max-width: 100%; +} + +.hoho a { + color: inherit; + text-decoration: none; +} + +.hoho button { + font: inherit; + color: inherit; + border: 0; + background: none; + cursor: pointer; +} + +.hoho ul, +.hoho ol { + margin: 0; + padding: 0; + list-style: none; +} + +.hoho blockquote, +.hoho figure, +.hoho dl, +.hoho dd { + margin: 0; +} + +.hoho :where(a, +.hoho button, +.hoho input, +.hoho select, +.hoho summary):focus-visible { + outline: 2px solid var(--c-teal); + outline-offset: 3px; + border-radius: 0.25rem; +} + +.hoho .sprite { + position: absolute; + width: 0; + height: 0; + overflow: hidden; +} + +.hoho .skip-link { + position: absolute; + left: -100vmax; + top: var(--sp-1); + z-index: 100; + padding: var(--sp-1) var(--sp-3); + border-radius: var(--r-pill); + background: var(--c-white); + color: var(--c-black); +} + +.hoho .skip-link:focus { + left: var(--sp-1); +} + +.hoho .container { + width: 100%; + max-width: var(--container); + margin-inline: auto; + padding-inline: var(--gutter); +} + +.hoho .icon { + width: 1rem; + height: 1rem; + flex: none; +} + +.hoho .icon--12 { + width: 0.75rem; + height: 0.75rem; +} + +.hoho .icon--14 { + width: 0.875rem; + height: 0.875rem; +} + +.hoho .icon--20 { + width: 1.25rem; + height: 1.25rem; +} + +.hoho .icon--24 { + width: 1.5rem; + height: 1.5rem; +} + +/* ========================================================= + Buttons, pills, chips + ========================================================= */ +.hoho .btn { + display: inline-flex; + align-items: center; + justify-content: center; + gap: var(--sp-1); + min-height: var(--control-h); + padding-inline: var(--sp-4); + border-radius: var(--r-pill); + font-weight: 700; + white-space: nowrap; + transition: transform 0.2s var(--ease), filter 0.2s var(--ease), background 0.2s var(--ease); +} + +.hoho .btn:hover { + filter: brightness(0.94); + transform: translateY(-1px); +} + +.hoho .btn--accent { + background: var(--c-accent); + color: var(--c-black); +} + +.hoho .btn--dark { + background: var(--c-black); + color: var(--c-white); +} + +.hoho .btn--white { + background: var(--c-white); + color: var(--c-black); + font-weight: 500; +} + +.hoho .btn--ghost { + border: 1px solid var(--c-line); + background: var(--c-white); + color: var(--c-black); + font-weight: 500; +} + +.hoho .btn--ghost:hover { + filter: none; + background: rgba(0, 0, 0, 0.04); +} + +.hoho .btn--wide { + justify-content: space-between; + width: 100%; + padding-inline: var(--sp-3); +} + +.hoho .icon-btn { + display: inline-grid; + place-items: center; + aspect-ratio: 1; + width: var(--control-h); + border-radius: var(--r-pill); + color: var(--c-white); + background: var(--c-glass); + -webkit-backdrop-filter: blur(12px); + backdrop-filter: blur(12px); + transition: background 0.2s var(--ease); +} + +.hoho .icon-btn:hover { + background: rgba(0, 0, 0, 0.7); +} + +.hoho .pill { + display: inline-flex; + align-items: center; + gap: var(--sp-1); + margin: 0; + padding: 0.375rem var(--sp-3); + border-radius: var(--r-pill); + color: var(--c-white); + background: var(--c-glass); + -webkit-backdrop-filter: blur(12px); + backdrop-filter: blur(12px); +} + +.hoho .chip { + display: inline-flex; + align-items: center; + gap: var(--sp-1); + padding: 0.125rem var(--sp-1); + border-radius: var(--r-pill); + font-size: 0.75rem; + font-weight: 700; + line-height: 1.6; + white-space: nowrap; +} + +.hoho .chip--accent { + background: var(--c-accent); + color: var(--c-black); +} + +.hoho .chip--glass { + color: var(--c-white); + background: var(--c-glass); + font-weight: 400; + -webkit-backdrop-filter: blur(12px); + backdrop-filter: blur(12px); +} + +.hoho .rating { + position: absolute; + left: var(--sp-2); + top: var(--sp-2); + z-index: 2; + display: inline-flex; + align-items: center; + gap: 0.25rem; + padding: 0.125rem var(--sp-1); + border-radius: var(--r-pill); + color: var(--c-white); + background: var(--c-glass); + -webkit-backdrop-filter: blur(12px); + backdrop-filter: blur(12px); +} + +.hoho .rating__star { + color: var(--c-accent); +} + +.hoho .rating b { + font-size: 0.875rem; + font-weight: 500; +} + +.hoho .rating i { + font-size: 0.75rem; + font-style: normal; + font-weight: 500; + opacity: 0.3; +} + +/* key / value pairs used on the cards */ +.hoho .meta { + display: flex; + flex-direction: column; + gap: 0.25rem; + min-width: 0; +} + +.hoho .meta__k { + font-size: 0.75rem; + font-weight: 500; +} + +.hoho .meta__v { + font-size: 1rem; + font-weight: 800; +} + +/* ========================================================= + Circular "ring" badge (scroll cue, book now, back to top) + ========================================================= */ +.hoho .ring-badge { + position: relative; + display: grid; + place-items: center; + aspect-ratio: 1; + width: clamp(3.25rem, 2.6rem + 2vw, 4.5rem); + flex: none; +} + +.hoho .ring-badge__ring { + position: absolute; + inset: 0; + width: 100%; + height: 100%; + opacity: 0.75; + animation: spin 16s linear infinite; +} + +.hoho .ring-badge__text { + fill: currentColor; + font-size: 0.75rem; + font-weight: 700; + letter-spacing: 0.04em; + text-transform: uppercase; +} + +.hoho .ring-badge__dot { + display: grid; + place-items: center; + padding: var(--sp-1); + border-radius: var(--r-pill); + color: var(--c-white); + background: var(--c-glass); + -webkit-backdrop-filter: blur(12px); + backdrop-filter: blur(12px); + transition: transform 0.2s var(--ease); +} + +.hoho .ring-badge:hover .ring-badge__dot { + transform: scale(1.08); +} + +.hoho .ring-badge--accent .ring-badge__dot, +.hoho .dcard:hover .ring-badge--card .ring-badge__dot, +.hoho .dcard:focus-within .ring-badge--card .ring-badge__dot, +.hoho .tcard:hover .ring-badge--card .ring-badge__dot, +.hoho .tcard:focus-within .ring-badge--card .ring-badge__dot, +.hoho .acard:hover .ring-badge--card .ring-badge__dot, +.hoho .acard:focus-within .ring-badge--card .ring-badge__dot { + color: var(--c-black); + background: var(--c-accent); +} + +.hoho .rail:hover .dcard.is-active:not(:hover):not(:focus-within) .ring-badge__dot, +.hoho .rail:hover .acard.is-active:not(:hover):not(:focus-within) .ring-badge__dot, +.hoho .bus__grid:hover .tcard.is-active:not(:hover):not(:focus-within) .ring-badge__dot { + color: var(--c-white); + background: var(--c-glass); +} + +.hoho .ring-badge--scroll { + position: absolute; + left: 50%; + bottom: 0; + z-index: 5; + /* dark ink stays legible over both the teal hero foot and the white section below */ + color: var(--c-ink); + transform: translate(-50%, 50%); +} + +.hoho .ring-badge--card { + width: clamp(2.875rem, 2.4rem + 1.6vw, 3.875rem); + color: var(--c-white); +} + +.hoho .ring-badge--card .ring-badge__text { + font-size: 0.875rem; +} + +.hoho .ring-badge--card .ring-badge__dot { + padding: 0.4375rem; +} + +.hoho .ring-badge--top { + position: absolute; + left: 50%; + top: 0; + color: var(--c-ink); + transform: translate(-50%, -50%); +} + +.hoho .ring-badge--top .ring-badge__text { + font-size: 0.625rem; + letter-spacing: 0.02em; +} + +.hoho .ring-badge--scroll .ring-badge__dot .icon { + animation: nudge 2s var(--ease) infinite; +} + +@keyframes spin { + to { + transform: rotate(360deg); + } +} + +@keyframes nudge { + + 0%, + 60%, + 100% { + transform: translateY(0); + } + + 30% { + transform: translateY(0.1875rem); + } +} + +/* ========================================================= + Header + ========================================================= */ +.hoho .site-header { + position: absolute; + inset: var(--page-inset) 0 auto; + z-index: 20; + padding-block: var(--sp-4); + color: var(--c-white); +} + +.hoho .site-header.is-stuck { + position: fixed; + inset-block-start: 0; + padding-block: var(--sp-2); + background: rgba(0, 0, 0, 0.55); + -webkit-backdrop-filter: blur(12px); + backdrop-filter: blur(12px); + animation: slide-down 0.3s var(--ease); +} + +@keyframes slide-down { + from { + transform: translateY(-100%); + } +} + +.hoho .header__inner { + display: flex; + align-items: center; + justify-content: space-between; + gap: var(--sp-4); +} + +.hoho .header__left { + display: flex; + align-items: center; + gap: clamp(1.5rem, 0.2rem + 4.5vw, 6rem); + min-width: 0; +} + +.hoho .header__logo .logo { + width: clamp(4.25rem, 3.6rem + 1.6vw, 5.6875rem); + height: auto; +} + +.hoho .header__actions { + display: flex; + align-items: center; + gap: var(--sp-1); +} + +.hoho .nav__list { + display: flex; + align-items: center; + gap: clamp(1rem, 0.1rem + 1.8vw, 2.5rem); +} + +.hoho .nav__link { + display: inline-flex; + align-items: center; + gap: var(--sp-1); + font-weight: 500; + white-space: nowrap; + transition: opacity 0.2s var(--ease); +} + +.hoho .nav__link:hover { + opacity: 0.7; +} + +.hoho .nav__item--has-menu { + position: relative; +} + +.hoho .nav__toggle .icon--chevron { + transition: transform 0.25s var(--ease); +} + +.hoho .nav__toggle[aria-expanded="true"] .icon--chevron { + transform: rotate(180deg); +} + +.hoho .nav__submenu { + position: absolute; + top: calc(100% + var(--sp-2)); + left: 0; + z-index: 5; + display: grid; + gap: 0.25rem; + min-width: max-content; + padding: var(--sp-1); + border-radius: 1rem; + color: var(--c-black); + background: var(--c-white); + box-shadow: 0 1.25rem 2.5rem rgba(0, 0, 0, 0.18); + opacity: 0; + visibility: hidden; + transform: translateY(-0.375rem); + transition: opacity 0.2s var(--ease), transform 0.2s var(--ease), visibility 0.2s; +} + +.hoho .nav__item--has-menu:hover .nav__submenu, +.hoho .nav__toggle[aria-expanded="true"]+.nav__submenu { + opacity: 1; + visibility: visible; + transform: translateY(0); +} + +.hoho .nav__submenu a { + display: block; + padding: var(--sp-1) var(--sp-3); + border-radius: var(--r-pill); + font-weight: 500; +} + +.hoho .nav__submenu a:hover { + background: rgba(0, 0, 0, 0.06); +} + +.hoho .nav__mobile-cta { + display: none; +} + +.hoho .burger { + display: none; + place-content: center; + place-items: center; + gap: 0.25rem; + aspect-ratio: 1; + width: var(--control-h); + border-radius: var(--r-pill); + background: var(--c-glass); + -webkit-backdrop-filter: blur(12px); + backdrop-filter: blur(12px); +} + +.hoho .burger span { + display: block; + width: 1.125rem; + height: 0.125rem; + border-radius: 1px; + background: var(--c-white); + transition: transform 0.25s var(--ease), opacity 0.25s var(--ease); +} + +.hoho .burger[aria-expanded="true"] span:nth-child(1) { + transform: translateY(0.375rem) rotate(45deg); +} + +.hoho .burger[aria-expanded="true"] span:nth-child(2) { + opacity: 0; +} + +.hoho .burger[aria-expanded="true"] span:nth-child(3) { + transform: translateY(-0.375rem) rotate(-45deg); +} + +/* ========================================================= + Hero + ========================================================= */ +.hoho .hero { + position: relative; + display: grid; + align-items: end; + min-height: clamp(34rem, 88svh, 56rem); + margin: var(--page-inset); + padding-block: calc(var(--header-h) + var(--sp-6)) clamp(3rem, 1.5rem + 6vw, 6rem); + border-radius: var(--r-xl); + isolation: isolate; +} + +.hoho .hero__media { + position: absolute; + inset: 0; + z-index: -1; + border-radius: inherit; + overflow: clip; +} + +.hoho .hero__img { + width: 100%; + height: 100%; + object-fit: cover; + object-position: center; +} + +/* Figma gradients: radial vignette + teal fade into the next section */ +.hoho .hero__scrim { + position: absolute; + inset: 0; + background: + radial-gradient(39.91% 77.37% at 60.22% 50%, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.5) 100%), + linear-gradient(180deg, rgba(44, 175, 194, 0) 51.6%, var(--c-teal) 100%); +} + +.hoho .hero__content { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: var(--sp-4); + text-align: left; +} + +.hoho .hero__eyebrow { + order: 1; + font-size: 1rem; +} + +.hoho .hero__title { + order: 2; + /* em keeps the two-line break ("Set out on" / "the journey.") at every size */ + max-width: 5.4em; + margin: 0; + font-size: var(--fs-hero); + font-weight: 500; + line-height: 1.05; + letter-spacing: -0.02em; + color: var(--c-white); +} + +.hoho .booking { + order: 3; + width: 100%; + max-width: 46.625rem; + padding: var(--sp-3); + border-radius: var(--r-card); + background: var(--c-white); + box-shadow: 0 1.5rem 3.5rem rgba(0, 0, 0, 0.18); +} + +.hoho .booking__row { + display: flex; + align-items: flex-end; + gap: var(--sp-3); +} + +.hoho .field { + display: flex; + flex: 1 1 0; + flex-direction: column; + gap: var(--sp-2); + min-width: 0; +} + +.hoho .field__label { + display: flex; + align-items: center; + gap: var(--sp-1); + font-size: 1rem; + font-weight: 500; + color: var(--c-black); +} + +.hoho .field__label label { + cursor: pointer; +} + +.hoho .select { + position: relative; + display: flex; + align-items: center; +} + +.hoho .select__input { + width: 100%; + min-width: 0; + min-height: var(--control-h); + padding: 0 calc(var(--sp-3) + 1.5rem) 0 var(--sp-3); + border: 1px solid var(--c-line); + border-radius: var(--r-pill); + font: inherit; + font-weight: 500; + color: var(--c-black); + background: var(--c-white); + appearance: none; + -webkit-appearance: none; + text-overflow: ellipsis; + transition: border-color 0.2s var(--ease); +} + +.hoho .select__input::placeholder { + color: var(--c-black); + opacity: 1; +} + +.hoho .select__input:hover { + border-color: rgba(0, 0, 0, 0.3); +} + +.hoho .select__input--date::-webkit-calendar-picker-indicator { + opacity: 0; + cursor: pointer; +} + +.hoho .select__chevron { + position: absolute; + right: var(--sp-3); + pointer-events: none; + color: var(--c-black); +} + +.hoho .booking__submit { + flex: none; +} + +/* ========================================================= + Section shell + section header + ========================================================= */ +.hoho .section { + padding-block: var(--sp-6); +} + +.hoho .section--tight { + padding-block-start: 0; +} + +.hoho .sec-head { + display: grid; + grid-template-columns: auto minmax(0, 1fr) auto; + align-items: center; + gap: clamp(1.5rem, 0.5rem + 3vw, 4rem); + margin-bottom: var(--sp-6); +} + +.hoho .sec-head__title { + margin: 0; + font-size: var(--fs-h2); + font-weight: 800; + line-height: 1.1; + letter-spacing: -0.03em; +} + +.hoho .sec-head__lead { + max-width: 40ch; + margin: 0; + opacity: 0.7; + font-weight: 500; +} + +.hoho .sec-head__actions { + display: flex; + flex-direction: column; + gap: var(--sp-1); + width: clamp(8rem, 6rem + 4vw, 9.125rem); +} + +.hoho .rail-nav { + display: flex; + gap: var(--sp-1); +} + +.hoho .rail-nav__btn { + flex: 1 1 0; + padding-inline: var(--sp-3); +} + +.hoho .rail-nav__btn[disabled] { + opacity: 0.35; + cursor: not-allowed; +} + +/* ========================================================= + Horizontal rails + ========================================================= */ +.hoho .rail { + display: flex; + gap: var(--gap); + overflow-x: auto; + scroll-snap-type: x mandatory; + scroll-behavior: smooth; + scrollbar-width: none; + /* negative margin + padding keeps the card glow from being clipped by the scroller */ + margin-inline: calc(var(--gap) * -1); + padding: var(--sp-4) var(--gap); +} + +.hoho .rail::-webkit-scrollbar { + display: none; +} + +.hoho .rail>* { + scroll-snap-align: start; +} + +.hoho .rail--dest>* { + flex: 0 0 calc((100% - 4 * var(--gap)) / 5); +} + +.hoho .rail--art>* { + flex: 0 0 calc((100% - 2 * var(--gap)) / 3); +} + +/* ========================================================= + Destination card + ========================================================= */ +.hoho .dcard { + position: relative; + display: flex; + flex-direction: column; + justify-content: flex-end; + aspect-ratio: 246 / 346; + padding: clamp(0.75rem, 0.4rem + 1vw, 1.25rem); + border-radius: var(--r-card); + color: var(--c-white); + overflow: hidden; + isolation: isolate; + transition: transform 0.3s var(--ease); +} + +.hoho .dcard:hover { + transform: translateY(-0.25rem); +} + +.hoho .dcard__img { + position: absolute; + inset: 0; + z-index: -2; + width: 100%; + height: 100%; + object-fit: cover; +} + +.hoho .dcard::after { + content: ""; + position: absolute; + inset: 0; + z-index: -1; + background: linear-gradient(180deg, rgba(0, 0, 0, 0) 35%, rgba(0, 0, 0, 0.65) 100%); +} + +/* highlighted card — gradients copied from Figma */ +.hoho .dcard.is-active, +.hoho .dcard:hover, +.hoho .dcard:focus-within { + box-shadow: 0 0.75rem 3.75rem 0 rgba(44, 175, 194, 0.5); +} + +.hoho .dcard.is-active::after, +.hoho .dcard:hover::after, +.hoho .dcard:focus-within::after { + background: + linear-gradient(180deg, rgba(255, 255, 255, 0) 51.6%, rgba(255, 255, 255, 0.4) 100%), + linear-gradient(0deg, rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.4)), + linear-gradient(180deg, rgba(44, 175, 194, 0) 37.33%, #2cafc2 84.53%); +} + +/* hovering any card in the rail hands the highlight over to it */ +.hoho .rail:hover .dcard.is-active:not(:hover):not(:focus-within), +.hoho .rail:focus-within .dcard.is-active:not(:hover):not(:focus-within) { + box-shadow: none; +} + +.hoho .rail:hover .dcard.is-active:not(:hover):not(:focus-within)::after, +.hoho .rail:focus-within .dcard.is-active:not(:hover):not(:focus-within)::after { + background: linear-gradient(180deg, rgba(0, 0, 0, 0) 35%, rgba(0, 0, 0, 0.65) 100%); +} + +.hoho .dcard__desc { + position: absolute; + left: clamp(0.75rem, 0.4rem + 1vw, 1.25rem); + right: clamp(0.75rem, 0.4rem + 1vw, 1.25rem); + top: clamp(2.75rem, 2rem + 2vw, 3.5rem); + opacity: 0; + transform: translateY(-0.375rem); + transition: opacity 0.25s var(--ease), transform 0.25s var(--ease); +} + +.hoho .dcard.is-active .dcard__desc, +.hoho .dcard:hover .dcard__desc, +.hoho .dcard:focus-within .dcard__desc { + opacity: 1; + transform: translateY(0); +} + +.hoho .rail:hover .dcard.is-active:not(:hover):not(:focus-within) .dcard__desc, +.hoho .rail:focus-within .dcard.is-active:not(:hover):not(:focus-within) .dcard__desc { + opacity: 0; + transform: translateY(-0.375rem); +} + +.hoho .dcard__desc-k { + display: block; + font-size: 0.75rem; + font-weight: 500; + opacity: 0.5; +} + +.hoho .dcard__desc p { + margin: 0.25rem 0 0; + font-size: 0.875rem; + font-weight: 500; + line-height: 1.45; +} + +.hoho .dcard__body { + display: grid; + gap: var(--sp-2); +} + +.hoho .dcard__title { + margin: 0; + font-size: var(--fs-card); + font-weight: 500; + letter-spacing: -0.01em; +} + +.hoho .dcard__meta { + display: flex; + align-items: flex-end; + justify-content: space-between; + gap: var(--sp-2); +} + +.hoho .dcard__meta .ring-badge { + margin-inline-start: auto; +} + +/* ========================================================= + Open Top Bus Tours (promo + 2x2 grid) + ========================================================= */ +.hoho .bus { + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); + gap: var(--gap); + align-items: start; +} + +.hoho .bus__grid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: var(--gap); +} + +.hoho .promo { + position: relative; + display: flex; + flex-direction: column; + aspect-ratio: 416 / 526; + padding: clamp(1.25rem, 0.6rem + 2vw, 2.5rem); + border-radius: var(--r-card); + background: var(--c-teal-05); + overflow: hidden; + isolation: isolate; +} + +.hoho .promo__route { + position: absolute; + inset: 0; + z-index: -1; + width: 100%; + height: 100%; + opacity: 0.5; +} + +.hoho .promo__head { + display: flex; + align-items: flex-start; + justify-content: space-between; + gap: var(--sp-3); +} + +.hoho .promo__title { + margin: 0; + font-size: var(--fs-h2); + font-weight: 800; + line-height: 1.1; + letter-spacing: -0.03em; + opacity: 0.8; +} + +.hoho .promo__chip { + align-self: flex-start; + margin-top: calc(var(--sp-1) * -1); + transform: rotate(-6deg); +} + +.hoho .promo__bus { + position: relative; + /* basis 0 so the coach takes only the space the title and note leave over */ + flex: 1 1 0; + display: grid; + place-items: center; + min-height: 0; + margin-inline: clamp(-2rem, -0.5rem - 3vw, -0.75rem); + /* padding-block: var(--sp-3) var(--sp-4); */ + padding-left: 2.5rem; +} + +.hoho .promo__bus img { + width: 100%; + height: 100%; + /* grid items default to min-height:auto, which would keep the intrinsic height */ + min-height: 0; + object-fit: contain; + object-position: left; + /* Figma tints the blue coach towards the teal brand colour */ + filter: hue-rotate(-32deg) saturate(1.15) drop-shadow(0 1rem 1.5rem rgba(0, 0, 0, 0.18)); +} + +.hoho .promo__note { + margin: 0; + margin-inline-start: auto; + max-width: 15rem; + font-weight: 500; + color: var(--c-teal); +} + +/* ========================================================= + Wide tour card + ========================================================= */ +.hoho .tcard { + position: relative; + display: flex; + flex-direction: column; + justify-content: space-between; + aspect-ratio: 416 / 251; + padding: clamp(0.875rem, 0.5rem + 1vw, 1.25rem); + border-radius: var(--r-card); + color: var(--c-white); + overflow: hidden; + isolation: isolate; + transition: transform 0.3s var(--ease); +} + +.hoho .tcard:hover { + transform: translateY(-0.25rem); +} + +.hoho .tcard__img { + position: absolute; + inset: 0; + z-index: -2; + width: 100%; + height: 100%; + object-fit: cover; +} + +.hoho .tcard::after { + content: ""; + position: absolute; + inset: 0; + z-index: -1; + background: linear-gradient(180deg, rgba(0, 0, 0, 0.45) 0%, rgba(0, 0, 0, 0.1) 45%, rgba(0, 0, 0, 0.6) 100%); +} + +.hoho .tcard.is-active, +.hoho .tcard:hover, +.hoho .tcard:focus-within { + box-shadow: 0 0.75rem 3.75rem 0 rgba(44, 175, 194, 0.5); +} + +.hoho .tcard.is-active::after, +.hoho .tcard:hover::after, +.hoho .tcard:focus-within::after { + background: + radial-gradient(53.59% 137.34% at 50% 46.41%, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.4) 100%), + linear-gradient(0deg, rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.4)), + linear-gradient(180deg, rgba(44, 175, 194, 0) 37.33%, #2cafc2 84.53%); +} + +.hoho .bus__grid:hover .tcard.is-active:not(:hover):not(:focus-within), +.hoho .bus__grid:focus-within .tcard.is-active:not(:hover):not(:focus-within) { + box-shadow: none; +} + +.hoho .bus__grid:hover .tcard.is-active:not(:hover):not(:focus-within)::after, +.hoho .bus__grid:focus-within .tcard.is-active:not(:hover):not(:focus-within)::after { + background: linear-gradient(180deg, rgba(0, 0, 0, 0.45) 0%, rgba(0, 0, 0, 0.1) 45%, rgba(0, 0, 0, 0.6) 100%); +} + +.hoho .tcard__k { + font-size: 0.75rem; + font-weight: 500; + opacity: 0.9; +} + +.hoho .tcard__title { + max-width: 14ch; + margin: 0; + font-size: var(--fs-card); + font-weight: 500; + line-height: 1.15; + letter-spacing: -0.01em; +} + +.hoho .tcard__bottom { + display: flex; + align-items: flex-end; + justify-content: space-between; + gap: var(--sp-2); +} + +/* ========================================================= + About + ========================================================= */ +.hoho .about { + display: grid; + grid-template-columns: minmax(0, 0.85fr) minmax(0, 1fr); + align-items: center; + gap: clamp(1.5rem, 0.5rem + 3vw, 3rem); +} + +.hoho .about__art { + position: relative; + display: grid; + place-items: center; + aspect-ratio: 4 / 3; + color: var(--c-teal); +} + +.hoho .about__glow { + display: none; +} + +/* straight speed-trail band running along the coach's axis */ +.hoho .about__trail { + position: absolute; + left: -34%; + right: -34%; + top: 42%; + height: 28%; + background: linear-gradient(90deg, + rgba(44, 175, 194, 0) 0%, + rgba(44, 175, 194, 0.16) 22%, + rgba(44, 175, 194, 0.2) 55%, + rgba(44, 175, 194, 0) 100%); + /* small blur only — the band keeps its straight parallel edges */ + filter: blur(2px); + /* 25deg == the roof ridge angle, measured off the artwork itself */ + transform: rotate(32deg); + pointer-events: none; +} + +/* the arcs sit in front of the bus, as in the reference */ +.hoho .about__arcs { + position: absolute; + z-index: 2; + inset: -12% 12% 2%; + width: auto; + height: 98%; + pointer-events: none; +} + +.hoho .about__bus { + position: relative; + z-index: 1; + display: grid; + place-items: center; + width: 92%; +} + +.hoho .about__bus img { + width: 100%; + height: auto; + object-fit: contain; + filter: drop-shadow(0 1.5rem 2.5rem rgba(0, 0, 0, 0.25)); +} + +.hoho .about__body { + display: grid; + gap: clamp(1.25rem, 0.8rem + 1.4vw, 1.8125rem); +} + +.hoho .about__head { + display: flex; + align-items: center; + justify-content: space-between; + gap: var(--sp-3); + flex-wrap: wrap; +} + +.hoho .about__title { + position: relative; + margin: 0; + padding-right: 1.5rem; + font-size: var(--fs-h2); + font-weight: 800; + letter-spacing: -0.03em; + opacity: 0.8; +} + +.hoho .about__chip { + position: absolute; + right: 0; + bottom: -0.75rem; + transform: rotate(-6deg); +} + +.hoho .about__text { + margin: 0; + opacity: 0.7; + font-weight: 500; + text-align: justify; +} + +.hoho .stats { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: var(--sp-4); +} + +.hoho .stat { + display: flex; + align-items: flex-end; + gap: 0.75rem; +} + +.hoho .stat__num { + margin: 0; + font-size: var(--fs-h2); + font-weight: 800; + line-height: 1; + letter-spacing: -0.03em; +} + +.hoho .stat__num span { + color: var(--c-teal); +} + +.hoho .stat__label { + opacity: 0.5; + font-weight: 500; +} + +/* ========================================================= + Testimonials marquee + ========================================================= */ +.hoho .testimonials__head { + display: grid; + justify-items: center; + gap: var(--sp-3); + margin-bottom: var(--sp-6); + text-align: center; +} + +.hoho .testimonials__title { + margin: 0; + font-size: var(--fs-h2); + font-weight: 800; + letter-spacing: -0.03em; +} + +.hoho .testimonials__lead { + max-width: 42ch; + margin: 0; + opacity: 0.5; + font-weight: 500; +} + +.hoho .marquee { + position: relative; + overflow: hidden; + -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); + mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); +} + +.hoho .marquee__route { + position: absolute; + inset: 0; + width: 100%; + height: 100%; + opacity: 0.6; + pointer-events: none; +} + +.hoho .marquee__track { + display: flex; + align-items: center; + gap: var(--gap); + width: max-content; + padding-block: var(--sp-3); + animation: marquee 60s linear infinite; +} + +.hoho .marquee:hover .marquee__track, +.hoho .marquee:focus-within .marquee__track { + animation-play-state: paused; +} + +@keyframes marquee { + to { + transform: translateX(calc(-50% - var(--gap) / 2)); + } +} + +.hoho .quote { + display: grid; + gap: var(--sp-3); + flex: none; + width: clamp(17rem, 14rem + 12vw, 26rem); + padding: var(--sp-4) var(--sp-5); + border-radius: var(--r-card); + background: var(--c-teal-05); + -webkit-backdrop-filter: blur(20px); + backdrop-filter: blur(20px); +} + +.hoho .quote--lg { + width: clamp(19rem, 15rem + 16vw, 32.875rem); +} + +.hoho .quote--sm { + width: clamp(15rem, 12rem + 9vw, 21.375rem); +} + +.hoho .quote__head { + display: flex; + align-items: center; + gap: 0.75rem; +} + +.hoho .quote__avatar { + aspect-ratio: 1; + width: 3rem; + border-radius: 50%; + object-fit: cover; +} + +.hoho .quote__head b { + display: block; + font-weight: 700; +} + +.hoho .quote__head i { + font-style: normal; + font-weight: 500; + color: var(--c-teal); +} + +.hoho .quote blockquote { + opacity: 0.5; + font-weight: 500; + text-align: justify; +} + +/* ========================================================= + Article card + ========================================================= */ +.hoho .acard { + display: flex; + flex-direction: column; + border-radius: var(--r-card); + background: var(--c-white); + transition: transform 0.3s var(--ease); +} + +.hoho .acard:hover { + transform: translateY(-0.25rem); +} + +.hoho .acard.is-active { + background: var(--c-teal-05); +} + +.hoho .acard__media { + position: relative; + aspect-ratio: 416 / 251; + border-radius: var(--r-card); + color: var(--c-white); + overflow: hidden; + isolation: isolate; +} + +.hoho .acard__img { + position: absolute; + inset: 0; + z-index: -2; + width: 100%; + height: 100%; + object-fit: cover; +} + +.hoho .acard__media::after { + content: ""; + position: absolute; + inset: 0; + z-index: -1; + background: linear-gradient(180deg, rgba(0, 0, 0, 0.35) 0%, rgba(0, 0, 0, 0.05) 40%, rgba(0, 0, 0, 0.65) 100%); +} + +.hoho .acard.is-active .acard__media::after, +.hoho .acard:hover .acard__media::after, +.hoho .acard:focus-within .acard__media::after { + background: + radial-gradient(53.59% 137.34% at 50% 46.41%, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.4) 100%), + linear-gradient(0deg, rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.4)), + linear-gradient(180deg, rgba(44, 175, 194, 0) 37.33%, #2cafc2 84.53%); +} + +.hoho .acard.is-active .acard__media, +.hoho .acard:hover .acard__media, +.hoho .acard:focus-within .acard__media { + box-shadow: 0 0.75rem 3.75rem 0 rgba(44, 175, 194, 0.5); +} + +.hoho .rail:hover .acard.is-active:not(:hover):not(:focus-within) { + background: var(--c-white); +} + +.hoho .rail:hover .acard.is-active:not(:hover):not(:focus-within) .acard__media { + box-shadow: none; +} + +.hoho .rail:hover .acard.is-active:not(:hover):not(:focus-within) .acard__media::after { + background: linear-gradient(180deg, rgba(0, 0, 0, 0.35) 0%, rgba(0, 0, 0, 0.05) 40%, rgba(0, 0, 0, 0.65) 100%); +} + +.hoho .acard__time { + position: absolute; + left: var(--sp-2); + top: var(--sp-2); +} + +.hoho .acard__overlay { + position: absolute; + inset: auto 0 0; + display: flex; + align-items: flex-end; + justify-content: space-between; + gap: var(--sp-2); + padding: clamp(0.875rem, 0.5rem + 1vw, 1.5rem); +} + +.hoho .acard__title { + max-width: 17ch; + margin: 0; + font-size: var(--fs-card); + font-weight: 500; + line-height: 1.15; + letter-spacing: -0.01em; +} + +.hoho .acard__excerpt { + margin: 0; + padding: var(--sp-4) var(--sp-4) var(--sp-5); + opacity: 0.7; + font-weight: 500; + text-align: justify; +} + +.hoho .acard.is-active .acard__excerpt, +.hoho .acard:hover .acard__excerpt, +.hoho .acard:focus-within .acard__excerpt { + opacity: 1; + color: var(--c-teal); +} + +.hoho .acard.is-active, +.hoho .acard:hover, +.hoho .acard:focus-within { + background: var(--c-teal-05); +} + +.hoho .rail:hover .acard.is-active:not(:hover):not(:focus-within) .acard__excerpt { + opacity: 0.7; + color: inherit; +} + +/* ========================================================= + FAQ + ========================================================= */ +.hoho .faq { + position: relative; + margin: var(--page-inset); + padding-block: var(--sp-6); + border-radius: var(--r-xl); + background: var(--c-teal-05); + overflow: hidden; + isolation: isolate; +} + +.hoho .faq__watermark { + position: absolute; + left: clamp(1rem, -1rem + 6vw, 4rem); + bottom: clamp(-2rem, -6vw, -1rem); + z-index: -1; + font-size: clamp(6rem, 2rem + 16vw, 15rem); + font-weight: 800; + letter-spacing: -0.04em; + line-height: 1; + color: transparent; + -webkit-text-stroke: 1px rgba(44, 175, 194, 0.35); + pointer-events: none; + user-select: none; +} + +.hoho .faq__inner { + display: grid; + grid-template-columns: minmax(0, 0.55fr) minmax(0, 1fr); + gap: clamp(2rem, 0.5rem + 6vw, 8.375rem); + align-items: start; +} + +.hoho .faq__intro { + display: grid; + gap: var(--sp-4); +} + +.hoho .faq__title { + margin: 0; + font-size: var(--fs-h2); + font-weight: 800; + letter-spacing: -0.03em; +} + +.hoho .faq__lead { + margin: 0; + opacity: 0.7; + font-weight: 500; +} + +.hoho .accordion { + display: grid; + gap: var(--sp-4); +} + +.hoho .acc+.acc { + border-top: 1px solid var(--c-line); + padding-top: var(--sp-4); +} + +.hoho .acc h3 { + margin: 0; + font-size: inherit; + font-weight: inherit; +} + +.hoho .acc__q { + display: flex; + align-items: center; + justify-content: space-between; + gap: var(--sp-3); + width: 100%; + padding: 0; + font-weight: 500; + text-align: left; + transition: color 0.2s var(--ease); +} + +.hoho .acc__q .icon { + opacity: 0.3; +} + +.hoho .acc__minus { + display: none; +} + +.hoho .acc__q[aria-expanded="true"] { + color: var(--c-teal); + font-weight: 700; +} + +.hoho .acc__q[aria-expanded="true"] .icon { + opacity: 1; +} + +.hoho .acc__q[aria-expanded="true"] .acc__plus { + display: none; +} + +.hoho .acc__q[aria-expanded="true"] .acc__minus { + display: block; +} + +.hoho .acc__a { + display: grid; + grid-template-rows: 0fr; + transition: grid-template-rows 0.3s var(--ease); +} + +.hoho .acc__q[aria-expanded="true"]+.acc__a { + grid-template-rows: 1fr; +} + +.hoho .acc__a>* { + overflow: hidden; +} + +.hoho .acc__a p { + margin: 0; + padding-top: var(--sp-4); + opacity: 0.7; + font-weight: 500; + text-align: justify; +} + +/* ========================================================= + Footer + ========================================================= */ +.hoho .footer { + position: relative; + margin: calc(var(--sp-6) + var(--page-inset)) var(--page-inset) var(--page-inset); + padding-block: var(--sp-6) 0; + border-radius: var(--r-xl); + color: var(--c-white); + background: var(--c-black); +} + +.hoho .footer__inner { + display: grid; + grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr); + gap: clamp(2rem, 0.5rem + 5vw, 6rem); + padding-bottom: var(--sp-6); +} + +.hoho .footer__logo .logo { + width: clamp(5rem, 4rem + 2.5vw, 7.125rem); + height: auto; +} + +.hoho .footer__brand { + display: grid; + gap: var(--sp-4); + align-content: start; +} + +.hoho .footer__about { + margin: 0; + opacity: 0.5; + font-weight: 500; + text-align: justify; +} + +.hoho .footer__cols { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: var(--sp-4); + justify-items: start; +} + +.hoho .footer__cols ul { + display: grid; + gap: 0.75rem; +} + +.hoho .footer__ct { + margin: 0 0 var(--sp-3); + font-size: 1rem; + font-weight: 700; + color: var(--c-teal); +} + +.hoho .footer__cols a { + opacity: 0.5; + font-weight: 500; + transition: opacity 0.2s var(--ease); +} + +.hoho .footer__cols a:hover { + opacity: 1; +} + +.hoho .footer__bar { + display: grid; + grid-template-columns: minmax(0, 1.2fr) minmax(0, 1.4fr) minmax(0, 1fr); + align-items: center; + gap: var(--sp-4); + padding-block: var(--sp-4); + border-top: 1px solid rgba(255, 255, 255, 0.2); +} + +.hoho .footer__copy { + margin: 0; + font-weight: 500; +} + +.hoho .socials { + display: flex; + align-items: center; + justify-content: center; + gap: var(--sp-5); +} + +/* dashed rules either side of the social icons, as in the design */ +.hoho .socials::before, +.hoho .socials::after { + content: ""; + flex: 1 1 clamp(2rem, 8vw, 11rem); + border-top: 1px dashed rgba(255, 255, 255, 0.3); +} + +.hoho .socials::before { + margin-inline-end: var(--sp-4); +} + +.hoho .socials::after { + margin-inline-start: var(--sp-4); +} + +.hoho .socials li { + flex: none; +} + +.hoho .socials a { + display: grid; + place-items: center; + transition: opacity 0.2s var(--ease); +} + +.hoho .socials a:hover { + opacity: 0.7; +} + +.hoho .support { + position: absolute; + right: clamp(1.5rem, 0.5rem + 3vw, 4rem); + bottom: 0; + z-index: 2; + display: grid; + place-items: center; + color: var(--c-white); +} + +.hoho .support__ring { + position: absolute; + aspect-ratio: 1; + scale: 140%; + opacity: 0.5; + top: -1.5rem; +} + +.hoho .support__tab { + display: grid; + place-items: center; + padding: var(--sp-4); + padding-bottom: clamp(2rem, 1rem + 3vw, 3rem); + border-radius: var(--r-pill) var(--r-pill) 0 0; + background: linear-gradient(180deg, rgba(44, 175, 194, 0.99) 0%, var(--c-teal-20) 100%); + box-shadow: 0 0.75rem 8.25rem var(--c-teal); + -webkit-backdrop-filter: blur(4px); + backdrop-filter: blur(4px); + transition: transform 0.2s var(--ease); +} + +.hoho .support:hover .support__tab { + transform: translateY(-0.25rem); +} + +/* ========================================================= + Responsive + ========================================================= */ +@media (max-width: 78rem) { +.hoho .rail--dest>* { + flex: 0 0 calc((100% - 3 * var(--gap)) / 4); + } + +} + +@media (max-width: 68.75rem) { +.hoho .booking__row { + flex-wrap: wrap; + } + +.hoho .field { + flex: 1 1 14rem; + } + +.hoho .booking__submit { + flex: 1 1 100%; + } + +.hoho .sec-head { + grid-template-columns: minmax(0, 1fr) auto; + } + +.hoho .sec-head__lead { + grid-column: 1 / -1; + grid-row: 2; + max-width: none; + } + +.hoho .rail--dest>* { + flex: 0 0 calc((100% - 2 * var(--gap)) / 3); + } + +.hoho .bus { + grid-template-columns: minmax(0, 1fr); + } + +.hoho .promo { + aspect-ratio: 16 / 9; + } + +.hoho .about { + grid-template-columns: minmax(0, 1fr); + } + +.hoho .about__art { + order: 2; + aspect-ratio: 16 / 9; + } + +.hoho .faq__inner { + grid-template-columns: minmax(0, 1fr); + } + +} + +@media (max-width: 60rem) { +.hoho .burger { + display: inline-grid; + } + +.hoho .header__cta { + display: none; + } + +.hoho .nav { + position: absolute; + top: calc(100% + var(--sp-2)); + right: var(--gutter); + left: var(--gutter); + padding: var(--sp-2); + border-radius: var(--r-card); + color: var(--c-black); + background: var(--c-white); + box-shadow: 0 1.5rem 3rem rgba(0, 0, 0, 0.22); + opacity: 0; + visibility: hidden; + transform: translateY(-0.5rem); + transition: opacity 0.25s var(--ease), transform 0.25s var(--ease), visibility 0.25s; + } + +.hoho .nav.is-open { + opacity: 1; + visibility: visible; + transform: translateY(0); + } + +.hoho .nav__list { + flex-direction: column; + align-items: stretch; + gap: 0; + } + +.hoho .nav__link { + width: 100%; + justify-content: space-between; + padding: var(--sp-2) var(--sp-3); + border-radius: var(--r-pill); + } + +.hoho .nav__link:hover { + opacity: 1; + background: rgba(0, 0, 0, 0.05); + } + +.hoho .nav__submenu { + position: static; + display: none; + padding: 0 0 var(--sp-1) var(--sp-3); + box-shadow: none; + opacity: 1; + visibility: visible; + transform: none; + } + +.hoho .nav__item--has-menu:hover .nav__submenu { + display: none; + } + +.hoho .nav__toggle[aria-expanded="true"]+.nav__submenu { + display: grid; + } + +.hoho .nav__mobile-cta { + display: block; + margin-top: var(--sp-1); + } + +.hoho .nav__cta { + width: 100%; + } + +.hoho .rail--art>* { + flex: 0 0 calc((100% - var(--gap)) / 2); + } + +.hoho .footer__inner { + grid-template-columns: minmax(0, 1fr); + } + +} + +@media (max-width: 48rem) { +.hoho .rail--dest>* { + flex: 0 0 calc((100% - var(--gap)) / 2); + } + +.hoho .bus__grid { + grid-template-columns: minmax(0, 1fr); + } + +.hoho .stats { + gap: var(--sp-3); + } + +.hoho .footer__bar { + grid-template-columns: minmax(0, 1fr); + justify-items: start; + } + +.hoho .socials::before, +.hoho .socials::after { + display: none; + } + +.hoho .support { + right: var(--gutter); + } + +} + +@media (max-width: 40rem) { +.hoho .hero { + min-height: clamp(30rem, 84svh, 44rem); + } + +.hoho .booking { + padding: var(--sp-2); + } + +.hoho .booking__row { + gap: var(--sp-2); + } + +.hoho .field { + flex: 1 1 100%; + } + +.hoho .sec-head { + grid-template-columns: minmax(0, 1fr); + gap: var(--sp-3); + } + +.hoho .sec-head__lead { + grid-row: auto; + } + +.hoho .sec-head__actions { + flex-direction: row; + width: 100%; + } + +.hoho .sec-head__actions .btn--wide { + width: auto; + flex: 1 1 auto; + } + +.hoho .rail--dest>* { + flex: 0 0 min(72%, 15rem); + } + +.hoho .rail--art>* { + flex: 0 0 min(85%, 22rem); + } + +.hoho .promo { + aspect-ratio: auto; + gap: var(--sp-4); + } + +.hoho .promo__note { + max-width: none; + margin-inline-start: 0; + } + +.hoho .stats { + grid-template-columns: minmax(0, 1fr); + } + +.hoho .support { + display: none; + } + +.hoho .footer__cols { + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: var(--sp-5) var(--sp-4); + } + +/* justified text tears open on narrow columns */ +.hoho .about__text, +.hoho .acard__excerpt, +.hoho .quote blockquote, +.hoho .acc__a p, +.hoho .footer__about { + text-align: left; + } + +} + +@media (prefers-reduced-motion: reduce) { +.hoho { + scroll-behavior: auto; + } + +.hoho *, +.hoho *::before, +.hoho *::after { + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.01ms !important; + } + +.hoho .rail { + scroll-behavior: auto; + } + +} + +/* ========================================================= + Tour archive — hero filter bar + ========================================================= */ +.hoho .hero--archive { + min-height: clamp(30rem, 78svh, 48rem); +} + +/* "Explore Tours" is short enough to stay on one line at every size */ +.hoho .hero--archive .hero__title { + max-width: none; +} + +.hoho .filters { + order: 3; + width: 100%; + border-radius: var(--r-card); + background: var(--c-white); + box-shadow: 0 1.5rem 3.5rem rgba(0, 0, 0, 0.18); +} + +.hoho .filters__row { + display: flex; + align-items: center; + gap: var(--sp-3); + padding: var(--sp-3); +} + +.hoho .fsearch, +.hoho .fsel { + position: relative; + display: flex; + flex: 1 1 0; + align-items: center; + min-width: 0; + min-height: var(--control-h); + border-radius: var(--r-pill); + transition: border-color 0.2s var(--ease); +} + +/* the search field carries the longest placeholder, so it takes a little more room */ +.hoho .fsearch { + flex-grow: 1.3; + border: 1px solid var(--c-white); + background: rgba(0, 0, 0, 0.05); +} + +.hoho .fsel { + border: 1px solid var(--c-line); + background: var(--c-white); +} + +.hoho .fsel:hover { + border-color: rgba(0, 0, 0, 0.3); +} + +.hoho .fsearch__icon, +.hoho .fsel__icon { + position: absolute; + left: var(--sp-3); + pointer-events: none; + color: var(--c-black); +} + +.hoho .fsel__chevron { + position: absolute; + right: var(--sp-3); + pointer-events: none; + color: var(--c-black); +} + +.hoho .fsearch__input, +.hoho .fsel__input { + width: 100%; + min-width: 0; + min-height: var(--control-h); + padding: 0 calc(var(--sp-3) + 1.5rem); + border: 0; + border-radius: inherit; + font: inherit; + font-weight: 500; + color: var(--c-black); + background: transparent; + appearance: none; + -webkit-appearance: none; + text-overflow: ellipsis; +} + +.hoho .fsearch__input { + padding-inline: calc(var(--sp-3) + 1.375rem) var(--sp-2); + font-size: 0.875rem; +} + +.hoho .fsearch__input::placeholder { + color: var(--c-black); + opacity: 0.5; +} + +.hoho .fsearch__input::-webkit-search-cancel-button, +.hoho .fsearch__input::-webkit-search-decoration { + -webkit-appearance: none; +} + +/* the sort dropdown carries its label outside the pill, so it needs no lead icon */ +.hoho .fsel--bare .fsel__input { + padding-left: var(--sp-3); +} + +.hoho .filters__apply { + flex: none; +} + +.hoho .filters__bar { + display: flex; + align-items: center; + justify-content: space-between; + flex-wrap: wrap; + gap: var(--sp-3) var(--sp-4); + padding: var(--sp-3) var(--sp-3) var(--sp-3) var(--sp-4); + border-top: 1px solid var(--c-line); +} + +.hoho .filters__checks { + display: flex; + align-items: center; + flex-wrap: wrap; + gap: var(--sp-2) 2.5rem; +} + +.hoho .check { + display: inline-flex; + align-items: center; + gap: var(--sp-1); + cursor: pointer; +} + +.hoho .check__input { + position: absolute; + width: 1px; + height: 1px; + opacity: 0; + pointer-events: none; +} + +.hoho .check__box { + display: grid; + flex: none; + place-items: center; + width: 1rem; + height: 1rem; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 0.25rem; + color: transparent; + background: var(--c-white); + transition: color 0.2s var(--ease), background-color 0.2s var(--ease), border-color 0.2s var(--ease); +} + +.hoho .check:hover .check__box { + border-color: rgba(0, 0, 0, 0.45); +} + +.hoho .check__input:checked+.check__box { + color: var(--c-white); + border-color: var(--c-black); + background: var(--c-black); +} + +.hoho .check__input:focus-visible+.check__box { + outline: 2px solid var(--c-teal); + outline-offset: 2px; +} + +.hoho .check__text { + font-size: 1rem; + font-weight: 500; + opacity: 0.7; + transition: opacity 0.2s var(--ease); +} + +.hoho .check__input:checked~.check__text { + opacity: 1; +} + +.hoho .filters__sort { + display: flex; + align-items: center; + gap: var(--sp-2); +} + +.hoho .filters__sort-label { + display: inline-flex; + align-items: center; + gap: var(--sp-1); + font-size: 1rem; + font-weight: 500; + white-space: nowrap; +} + +.hoho .filters__sort-label label { + cursor: pointer; +} + +.hoho .filters__sort .fsel { + flex: none; + width: 8.8125rem; +} + +/* ========================================================= + Tour archive — result grid + ========================================================= */ +/* the script shows and hides cards, pages and buttons with the hidden + attribute, which the flex and grid display values would otherwise win against */ +.hoho [hidden] { + display: none !important; +} + +.hoho .results { + display: flex; + align-items: center; + justify-content: space-between; + flex-wrap: wrap; + gap: var(--sp-2) var(--sp-3); + margin-block-end: var(--sp-4); +} + +.hoho .results__count { + margin: 0; + font-size: 1rem; + font-weight: 500; + opacity: 0.7; +} + +.hoho .results__count b { + font-weight: 800; +} + +.hoho .results__reset { + flex: none; +} + +.hoho .tgrid__empty { + margin: 0; + padding-block: var(--sp-5); + font-size: 1.125rem; + font-weight: 500; + text-align: center; + opacity: 0.7; +} + +/* a button that reads as part of the sentence around it */ +.hoho .linkbtn { + padding: 0; + border: 0; + font: inherit; + color: var(--c-teal); + background: none; + text-decoration: underline; + cursor: pointer; +} + +.hoho .tgrid { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 2.5rem var(--gap); + margin: 0; + padding: 0; + list-style: none; +} + +.hoho .titem { + display: flex; + flex-direction: column; + align-items: center; + gap: var(--sp-3); +} + +/* landscape variant of the destination card used on the homepage rail */ +.hoho .dcard--wide { + width: 100%; + aspect-ratio: 416 / 251; +} + +/* the wider card gives the title and the key/value pairs more room to breathe */ +.hoho .dcard--wide .dcard__body { + gap: var(--sp-3); +} + +.hoho .dcard--wide .dcard__meta { + gap: var(--sp-4); +} + +.hoho .titem__desc { + width: 88.5%; + margin: 0; + font-size: 1rem; + font-weight: 500; + line-height: 1.5; + text-align: justify; + opacity: 0.7; + transition: color 0.25s var(--ease), opacity 0.25s var(--ease); +} + +.hoho .titem.is-active .titem__desc, +.hoho .titem:hover .titem__desc, +.hoho .titem:focus-within .titem__desc { + color: var(--c-teal); + opacity: 1; +} + +/* hovering any card in the grid hands the highlight over to it */ +.hoho .tgrid:hover .titem.is-active:not(:hover):not(:focus-within) .titem__desc, +.hoho .tgrid:focus-within .titem.is-active:not(:hover):not(:focus-within) .titem__desc { + color: inherit; + opacity: 0.7; +} + +.hoho .tgrid:hover .dcard.is-active:not(:hover):not(:focus-within), +.hoho .tgrid:focus-within .dcard.is-active:not(:hover):not(:focus-within) { + box-shadow: none; +} + +.hoho .tgrid:hover .dcard.is-active:not(:hover):not(:focus-within)::after, +.hoho .tgrid:focus-within .dcard.is-active:not(:hover):not(:focus-within)::after { + background: linear-gradient(180deg, rgba(0, 0, 0, 0) 35%, rgba(0, 0, 0, 0.65) 100%); +} + +.hoho .tgrid:hover .dcard.is-active:not(:hover):not(:focus-within) .ring-badge__dot, +.hoho .tgrid:focus-within .dcard.is-active:not(:hover):not(:focus-within) .ring-badge__dot { + color: var(--c-white); + background: var(--c-glass); +} + +/* ========================================================= + Tour archive — pagination + ========================================================= */ +.hoho .pager { + display: flex; + align-items: center; + justify-content: center; + flex-wrap: wrap; + gap: var(--sp-1); + margin-block-start: var(--sp-6); +} + +.hoho .pager__pages { + display: flex; + align-items: center; + gap: var(--sp-1); +} + +.hoho .pager__num, +.hoho .pager__btn { + display: inline-flex; + align-items: center; + justify-content: center; + gap: var(--sp-1); + min-height: var(--control-h); + padding: 0 var(--sp-3); + border: 0; + border-radius: var(--r-pill); + font: inherit; + font-weight: 500; + color: var(--c-black); + background: transparent; + cursor: pointer; + transition: color 0.2s var(--ease), background-color 0.2s var(--ease), border-color 0.2s var(--ease); +} + +.hoho .pager__num { + min-width: var(--control-h); + padding: 0 var(--sp-1); +} + +.hoho .pager__num:hover { + background: rgba(0, 0, 0, 0.05); +} + +.hoho .pager__num.is-current { + color: var(--c-white); + background: var(--c-black); +} + +.hoho .pager__btn { + border: 1px solid var(--c-line); + background: var(--c-white); +} + +.hoho .pager__btn--icon { + min-width: 4.5rem; +} + +.hoho .pager__btn:hover:not([disabled]) { + border-color: var(--c-black); +} + +.hoho .pager__btn[disabled] { + opacity: 0.4; + cursor: not-allowed; +} + +.hoho .pager__gap { + padding-inline: 0.25rem; + font-weight: 500; + opacity: 0.5; +} + +/* ========================================================= + Tour archive — responsive + ========================================================= */ +@media (max-width: 68.75rem) { +.hoho .filters__row { + flex-wrap: wrap; + } + +.hoho .fsearch, +.hoho .fsel { + flex: 1 1 12rem; + } + +.hoho .filters__apply { + flex: 1 1 100%; + } + +.hoho .tgrid { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + +} + +@media (max-width: 48rem) { +.hoho .filters__bar { + justify-content: flex-start; + } + +.hoho .filters__checks { + gap: var(--sp-2) var(--sp-5); + } + +} + +@media (max-width: 40rem) { +.hoho .filters__row { + gap: var(--sp-2); + padding: var(--sp-2); + } + +.hoho .fsearch, +.hoho .fsel { + flex: 1 1 100%; + } + +.hoho .filters__bar { + padding: var(--sp-3); + } + +.hoho .filters__sort { + width: 100%; + justify-content: space-between; + } + +.hoho .tgrid { + grid-template-columns: minmax(0, 1fr); + } + +.hoho .titem__desc { + width: 100%; + text-align: left; + } + +.hoho .pager__btn--icon { + min-width: 0; + } + +} + +/* ========================================================= + Tour details — hero + ========================================================= */ +.hoho .hero-tour { + position: relative; + display: grid; + align-items: end; + /* one scale drives the display word, the kicker and the figure, so the three + keep the proportions they have in the design at every width */ + --word: clamp(3rem, 0.4rem + 9.5vw, 11.25rem); + min-height: clamp(26rem, 62svh, 38rem); + margin: var(--page-inset); + padding-block: calc(var(--header-h) + var(--sp-5)) clamp(0.75rem, 0.4rem + 1vw, 1.5rem); + border-radius: var(--r-xl); + isolation: isolate; + overflow: clip; +} + +/* the sky photo is framed on its upper third so the grass at its foot stays out + of shot, and the wash over it carries the blue into the brand turquoise */ +.hoho .hero-tour__photo { + position: absolute; + inset: 0; + z-index: -2; + width: 100%; + height: 100%; + border-radius: inherit; + object-fit: cover; + object-position: center 26%; +} + +.hoho .hero-tour__sky { + position: absolute; + inset: 0; + z-index: -1; + border-radius: inherit; + background: + radial-gradient(70% 50% at 50% 100%, rgba(255, 255, 255, 0.3) 0%, rgba(255, 255, 255, 0) 70%), + linear-gradient(180deg, rgba(27, 147, 166, 0.82) 0%, rgba(44, 175, 194, 0.62) 45%, rgba(111, 208, 221, 0.78) 100%); +} + +.hoho .hero-tour__inner { + display: flex; + flex-direction: column; + align-items: center; +} + +/* the block is exactly as wide as the display word, so it can sit centred in + the hero while the breadcrumb and the kicker line up on the word's left edge */ +.hoho .hero-tour__block { + display: flex; + position: absolute; + top: 112px; + flex-direction: column; + align-items: flex-start; + gap: var(--sp-2); + width: max-content; + max-width: 100%; +} + +.hoho .crumbs__list { + display: flex; + align-items: center; + flex-wrap: wrap; + gap: var(--sp-1); + margin: 0; + padding: 0; + list-style: none; + font-size: 0.75rem; + font-weight: 500; +} + +.hoho .crumbs__list li+li::before { + content: "/"; + margin-inline-end: var(--sp-1); + opacity: 0.5; +} + +.hoho .crumbs__list a { + opacity: 0.5; + transition: opacity 0.2s var(--ease); +} + +.hoho .crumbs__list a:hover { + opacity: 1; +} + +.hoho .hero-tour__kicker { + margin: 0; + font-size: max(1.25rem, calc(var(--word) * 0.222)); + font-weight: 500; + letter-spacing: -0.01em; +} + +/* The figure overlaps the word, so the stage carries the display size and both + children are measured in em against it - the offsets are the Figma ones + (word at x487/y193 at 180px, figure at x756/y58, 263x447) expressed as ratios, + which keeps the composition identical at every width. */ +.hoho .hero-tour__stage { + position: relative; + align-self: stretch; + font-size: var(--word); + isolation: isolate; +} + +.hoho .hero-tour__word { + margin: 0; + font-size: 1em; + font-weight: 500; + line-height: 0.95; + letter-spacing: -0.02em; + color: var(--c-white); +} + +.hoho .hero-tour__figure { + position: absolute; + left: 2em; + top: -0.5em; + z-index: 1; + width: auto; + height: 2.48em; + object-fit: contain; + scale: 1.2; +} + +/* ========================================================= + Tour details — layout + ========================================================= */ +.hoho .tour__layout { + display: grid; + grid-template-columns: minmax(0, 1fr) 26rem; + align-items: start; + gap: clamp(1.5rem, 1rem + 1vw, 2rem); +} + +.hoho .tour__main { + display: flex; + flex-direction: column; + gap: var(--sp-5); + min-width: 0; +} + +.hoho .tour__block { + display: flex; + flex-direction: column; + gap: var(--sp-1); +} + +.hoho .tour__ct { + margin: 0; + font-size: 1rem; + font-weight: 700; +} + +.hoho .tour__text { + margin: 0; + font-size: 1rem; + font-weight: 500; + line-height: 1.6; + text-align: justify; + opacity: 0.7; +} + +.hoho .tour__text+.tour__text { + margin-block-start: var(--sp-3); +} + +/* --- title row --- */ +.hoho .tour-head { + display: flex; + align-items: center; + justify-content: space-between; + flex-wrap: wrap; + gap: var(--sp-3) var(--sp-4); +} + +.hoho .tour-head__title { + margin: 0; + font-size: clamp(1.75rem, 1.2rem + 2.2vw, 2.5rem); + font-weight: 500; + letter-spacing: -0.01em; +} + +.hoho .tmeta { + display: flex; + align-items: center; + flex-wrap: wrap; + gap: var(--sp-4); + font-size: 1rem; + font-weight: 500; +} + +.hoho .tmeta__item { + display: inline-flex; + align-items: center; + gap: var(--sp-1); +} + +.hoho .tmeta__item b { + font-weight: 500; +} + +.hoho .tmeta__item i { + font-size: 0.75rem; + font-style: normal; + opacity: 0.3; +} + +.hoho .tmeta__star { + color: var(--c-accent); +} + +.hoho .tmeta__icon { + opacity: 0.5; +} + +.hoho .tmeta__rule { + width: 1px; + height: 1.5rem; + background: var(--c-line); +} + +/* --- the four facts under the title --- */ +.hoho .facts { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: var(--sp-1); + margin: 0; + padding: 0; + list-style: none; +} + +.hoho .fact, +.hoho .note { + display: flex; + align-items: center; + gap: var(--sp-2); + min-width: 0; + border-radius: var(--r-card); + background: var(--c-teal-05); +} + +.hoho .fact { + padding: var(--sp-4) var(--sp-3); +} + +.hoho .fact__icon, +.hoho .note__icon { + flex: none; + color: var(--c-teal); +} + +.hoho .fact__text { + display: flex; + flex-direction: column; + min-width: 0; +} + +.hoho .fact__k { + font-size: 0.75rem; + font-weight: 500; + color: var(--c-teal); +} + +.hoho .fact__v { + font-size: 1rem; + font-weight: 500; +} + +/* --- gallery --- */ +.hoho .gallery { + display: grid; + grid-template-columns: 350fr 245fr 245fr; + gap: var(--sp-3); +} + +.hoho .gallery img { + width: 100%; + height: 100%; + aspect-ratio: 245 / 194; + border-radius: var(--r-xl); + object-fit: cover; +} + +.hoho .gallery__hero { + grid-row: span 2; + aspect-ratio: auto; + border-radius: var(--r-card); +} + +/* --- included / not included --- */ +.hoho .lists { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: var(--sp-4) clamp(1.5rem, 1rem + 1.5vw, 1.6875rem); +} + +.hoho .ilist { + display: flex; + flex-direction: column; + gap: var(--sp-3); +} + +.hoho .ilist__items { + display: flex; + flex-direction: column; + gap: var(--sp-3); + margin: 0; + padding: 0; + list-style: none; +} + +.hoho .ilist__items li { + display: flex; + align-items: center; + gap: var(--sp-3); +} + +.hoho .ilist__items p { + margin: 0; + font-size: 1rem; + font-weight: 500; + line-height: 1.5; + text-align: justify; + opacity: 0.7; +} + +.hoho .tick { + display: grid; + flex: none; + place-items: center; + width: 1.5rem; + height: 1.5rem; + border-radius: var(--r-pill); +} + +.hoho .tick--yes { + color: var(--c-green); + background: rgba(52, 199, 89, 0.1); +} + +.hoho .tick--no { + color: var(--c-red); + background: rgba(255, 56, 60, 0.1); +} + +/* --- good to know --- */ +.hoho .notes { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: var(--sp-1); + margin: 0; + padding: 0; + list-style: none; +} + +.hoho .note { + gap: var(--sp-2); + padding: var(--sp-4) var(--sp-3); +} + +.hoho .note p { + margin: 0; + font-size: 1rem; + font-weight: 500; + line-height: 1.4; +} + +/* --- the tinted key/value cards, shared by the policy row and the sidebar --- */ +.hoho .statcard { + display: flex; + align-items: center; + gap: var(--sp-2); + padding: var(--sp-4); + border-radius: var(--r-card); +} + +.hoho .statcard__icon { + flex: none; +} + +.hoho .statcard__text { + display: flex; + flex-direction: column; + min-width: 0; +} + +.hoho .statcard__k { + font-size: 0.75rem; + font-weight: 500; +} + +.hoho .statcard__v { + font-size: 1rem; + font-weight: 500; +} + +.hoho .statcard--yes { + background: rgba(52, 199, 89, 0.05); +} + +.hoho .statcard--yes .statcard__icon, +.hoho .statcard--yes .statcard__k { + color: var(--c-green); +} + +.hoho .statcard--no { + background: rgba(255, 56, 60, 0.05); +} + +.hoho .statcard--no .statcard__icon, +.hoho .statcard--no .statcard__k { + color: var(--c-red); +} + +.hoho .statcard--teal { + background: var(--c-teal-05); +} + +.hoho .statcard--teal .statcard__icon, +.hoho .statcard--teal .statcard__k { + color: var(--c-teal); +} + +.hoho .policy { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: var(--sp-3); + margin-block-start: var(--sp-3); +} + +/* ========================================================= + Tour details — booking sidebar + ========================================================= */ +.hoho .tour__aside { + position: sticky; + top: calc(var(--header-h) + var(--sp-3)); +} + +.hoho .bookcard { + display: flex; + flex-direction: column; + gap: var(--sp-1); + padding: var(--sp-3); + border: 1px solid var(--c-line); + border-radius: var(--r-card); + background: var(--c-white); +} + +.hoho .bookcard__title { + display: flex; + align-items: center; + gap: var(--sp-1); + margin: 0 0 var(--sp-1); + padding: var(--sp-1) var(--sp-1) 0; + font-size: 1rem; + font-weight: 500; +} + +.hoho .bookcard__price { + display: flex; + align-items: center; + justify-content: space-between; + flex-wrap: wrap; + gap: var(--sp-3); + padding: var(--sp-3); + border: 1px dashed var(--c-line); + border-radius: var(--r-card); +} + +.hoho .price { + display: grid; + grid-template-areas: + "k k" + "v u"; + align-items: baseline; + gap: 0 var(--sp-1); + margin: 0; +} + +.hoho .price__k { + grid-area: k; + font-size: 0.75rem; + font-weight: 500; + opacity: 0.3; +} + +.hoho .price__v { + grid-area: v; + font-size: 2rem; + font-weight: 500; + letter-spacing: -0.01em; +} + +.hoho .price__unit { + grid-area: u; + font-size: 0.75rem; + font-weight: 500; + opacity: 0.3; +} + +.hoho .bookcard__cta { + flex: none; +} + +/* ========================================================= + Tour details — responsive + ========================================================= */ +@media (max-width: 68.75rem) { +.hoho .tour__layout { + grid-template-columns: minmax(0, 1fr); + } + +.hoho .tour__aside { + position: static; + order: -1; + } + +.hoho .facts { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + +.hoho .notes { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + +} + +@media (max-width: 48rem) { +.hoho .gallery { + grid-template-columns: repeat(2, minmax(0, 1fr)); + grid-template-rows: auto; + aspect-ratio: auto; + } + +.hoho .gallery img { + aspect-ratio: 4 / 3; + } + +.hoho .gallery__hero { + grid-column: span 2; + grid-row: auto; + aspect-ratio: 16 / 9; + } + +.hoho .lists { + grid-template-columns: minmax(0, 1fr); + } + +} + +@media (max-width: 40rem) { +.hoho .hero-tour { + min-height: clamp(24rem, 70svh, 34rem); + } + +.hoho .facts, +.hoho .notes { + grid-template-columns: minmax(0, 1fr); + } + +.hoho .policy { + grid-template-columns: minmax(0, 1fr); + } + +.hoho .tour__text, +.hoho .ilist__items p { + text-align: left; + } + +.hoho .bookcard__price { + justify-content: center; + } + +.hoho .bookcard__cta { + width: 100%; + } + +} + diff --git a/astra-child-hoponhopoff/assets/chrome.js b/astra-child-hoponhopoff/assets/chrome.js new file mode 100644 index 0000000..3f15a38 --- /dev/null +++ b/astra-child-hoponhopoff/assets/chrome.js @@ -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" }); + }); + } +})(); diff --git a/astra-child-hoponhopoff/assets/sprite.svg b/astra-child-hoponhopoff/assets/sprite.svg new file mode 100644 index 0000000..7ab87c7 --- /dev/null +++ b/astra-child-hoponhopoff/assets/sprite.svg @@ -0,0 +1,176 @@ + diff --git a/astra-child-hoponhopoff/functions.php b/astra-child-hoponhopoff/functions.php new file mode 100644 index 0000000..84ba3dd --- /dev/null +++ b/astra-child-hoponhopoff/functions.php @@ -0,0 +1,126 @@ + true, 'flex-height' => true ) ); + register_nav_menus( + array( + 'hoho_primary' => __( 'HoHo — Header Menu', 'hoponhopoff' ), + 'hoho_quick' => __( 'HoHo — Footer: Quick Access', 'hoponhopoff' ), + 'hoho_tours' => __( 'HoHo — Footer: Tours', 'hoponhopoff' ), + 'hoho_account' => __( 'HoHo — Footer: User Account', 'hoponhopoff' ), + ) + ); +} ); + +/** + * Print the SVG icon sprite once, high in the footer, so + * resolves everywhere (header, footer, and the plugin's pages). + */ +add_action( 'wp_footer', function () { + // Reuse the plugin's guarded printer when available, so the sprite is never + // output twice on plugin pages. + if ( function_exists( 'vc_print_icon_sprite' ) ) { + vc_print_icon_sprite(); + return; + } + $sprite = get_stylesheet_directory() . '/assets/sprite.svg'; + if ( is_readable( $sprite ) ) { + echo file_get_contents( $sprite ); // phpcs:ignore + } +}, 1 ); + +/** + * Swap Astra's header/footer markup for ours. + * + * Astra prints its header via astra_header_markup() on the `astra_header` + * action, and its footer via astra_footer_markup() on `astra_footer`. We remove + * those and render our own template parts. Deferred to `wp` so Astra's parent + * functions.php (which registers the callbacks) has already loaded. + */ +add_action( 'wp', function () { + if ( function_exists( 'astra_header_markup' ) ) { + remove_action( 'astra_header', 'astra_header_markup' ); + } + add_action( 'astra_header', 'hoho_render_header' ); + + if ( function_exists( 'astra_footer_markup' ) ) { + remove_action( 'astra_footer', 'astra_footer_markup' ); + } + add_action( 'astra_footer', 'hoho_render_footer' ); +} ); + +function hoho_render_header() { + require get_stylesheet_directory() . '/inc/header.php'; +} +function hoho_render_footer() { + require get_stylesheet_directory() . '/inc/footer.php'; +} + +require get_stylesheet_directory() . '/inc/nav-walker.php'; + +/** + * The logo: a linked WordPress Custom Logo if one is set, otherwise the bundled + * "Hop On Hop Off" SVG wordmark. + */ +function hoho_logo() { + $home = esc_url( home_url( '/' ) ); + if ( has_custom_logo() ) { + $id = get_theme_mod( 'custom_logo' ); + $img = wp_get_attachment_image( $id, 'full', false, array( 'class' => 'logo' ) ); + if ( $img ) { + return ''; + } + } + ob_start(); + ?> + + '; +} diff --git a/astra-child-hoponhopoff/inc/footer.php b/astra-child-hoponhopoff/inc/footer.php new file mode 100644 index 0000000..d3ead3b --- /dev/null +++ b/astra-child-hoponhopoff/inc/footer.php @@ -0,0 +1,88 @@ + '#', + 'instagram' => '#', + 'telegram' => '#', + 'facebook' => '#', + ) +); + +$hoho_footer_col = function ( $location ) { + if ( ! has_nav_menu( $location ) ) { + return; + } + wp_nav_menu( + array( + 'theme_location' => $location, + 'container' => false, + 'items_wrap' => '
    %3$s
', + 'depth' => 1, + 'fallback_cb' => false, + ) + ); +}; +?> +
+ +
+ +
+ +
diff --git a/astra-child-hoponhopoff/inc/logo.php b/astra-child-hoponhopoff/inc/logo.php new file mode 100644 index 0000000..4324bf2 --- /dev/null +++ b/astra-child-hoponhopoff/inc/logo.php @@ -0,0 +1,88 @@ + + diff --git a/astra-child-hoponhopoff/inc/nav-walker.php b/astra-child-hoponhopoff/inc/nav-walker.php new file mode 100644 index 0000000..1f3ea03 --- /dev/null +++ b/astra-child-hoponhopoff/inc/nav-walker.php @@ -0,0 +1,58 @@ + + a + *