Quick Start
- Keep
index.htmlbeside theassetsdirectory and open it through a local web server. - Replace the Higher Ground name, trip copy and example departures in
index.html. - Replace every
hello@higherground.exampleaddress with your real enquiry address. These are placeholder email links, not a booking service. - Upload
index.htmlandassetsto your static host. The page does not require a build step.
The HTML loads GSAP, ScrollTrigger, Lenis and Google Fonts from their CDNs. The readable assets/script.js is loaded by default; switch the final script tag to script.min.js if you prefer the minified file.
Using It With Your Own Design
assets/style.css owns the complete visual identity. The JS uses data- attributes so you can restyle classes without changing the interactions. Keep each section's hooks together when moving it. Every initialiser checks for its section, so you can delete a complete section and the remaining ones still run.
The HTML is the full content model. With JavaScript disabled, the landscapes and route stories remain in reading order. The synchronous has-js head script is the enhancement signal and is removed if GSAP or ScrollTrigger cannot load. Do not add unguarded hidden states to your own text.
The desktop landscape window depends on the .is-aperture class, which the script adds only when pinning is supported. The default figures are normal document sections. Retain the positioned image wrapper and overflow clipping in the hero and company image: their photographs need the spare area for parallax.
Sections and options
Mountain opening
[data-hero] contains a photograph layer, a heading layer and ordinary navigation. Change the headline directly in the h1. The display scale is designed for a short phrase; check the single-line desktop and phone layouts if your title is longer than “GO HIGHER.”.
The photograph uses object-fit: cover. Adjust .hero__image's object-position to preserve your focal point. The scrim keeps white text readable: its upper edge protects navigation, its middle protects large display type, and its bottom protects the trip facts. Recheck contrast before reducing those values. Fine-pointer depth is intentionally mild; scroll supplies the larger movement.
Landscape aperture
[data-aperture] owns three [data-landscape] figures and the matching [data-landscape-jump] buttons, in the same order. Change each image, alt text, title and caption together. When adding a chapter, add both its figure and its button. The script derives the count from the figures.
The desktop pin has 1.35 viewport heights of travel. Change the 1.35 multiplier in the trigger's end function to adjust the pace. clipPath opens the viewport; scale belongs to the photographs inside it. On smaller screens, coarse pointers or reduced motion, pinning is skipped and the figures remain a vertical sequence. The chooser appears only when the pin is active.
Anchor links account for the pin spacer. Keep the real href="#landscapes" so navigation also works without JavaScript. Do not add CSS scroll-behavior: smooth; Lenis and CSS must not each animate the same scroll position.
Illustrated journey
[data-route] contains the native range, the SVG profile and the [data-route-panel] stories. Each panel carries a data-route-name used for the range's accessible value. Buttons with [data-route-jump] choose the same chapters as the range. Keep buttons and panels in matching order.
The range maps 0–100 to the length of the SVG path. If you edit the shape, change the d attribute on both [data-route-path] and [data-route-progress]; update the decorative filled area to fit. The diagram is illustrative, not real trail data. Publish a verified itinerary separately if your actual product needs one.
The default route contains all story panels. JS adds .is-explorer and hides only the inactive panels. Touch, keyboard arrows and chapter buttons update the same state. In reduced motion the marker changes position immediately.
Company and departures
The company image works best with people in the centre-right of a wide frame. The large heading sits at the lower left on a local scrim. The three native <details> rows below it can be edited, duplicated or removed without script changes.
There is no booking backend. Dates, group size and company details are fictional example content. Enquiry links open the visitor's email application with a subject line; they do not reserve a place, send a message automatically, take payment or check availability. Replace the placeholder email address or link to your own booking platform before launch.
Palette
The semantic tokens are at the top of assets/style.css:
| Token | Use |
|---|---|
--ground |
Limestone paper and light control surfaces |
--ink |
Forest text and dark sections |
--surface |
Glacier landscape ground |
--accent |
Fired-red active route marker and states |
--inverse |
White text over dark surfaces |
Each colour has a matching RGB triple for translucent treatments. Change both when reskinning. The root comment records measured solid and composited text contrast. Photographs provide most colour; the accent is limited to interaction states. This template has no palette picker.
Display type is Oswald 600; body type is DM Sans. Change --font-display, --font-display-weight and the Google Fonts link together when selecting another face. Check the hero and footer wordmarks at 375px after a font swap.
Images
The download includes four optimised, graded WebP derivatives in assets/img/. They are shared across sections to keep the transfer size small. assets/img-manifest.json records source URLs, crop dimensions, grade and quality settings.
| File | Crop | Appears in |
|---|---|---|
ridge.webp |
1920 × 1200 | Hero, high-path landscape and route story |
valley.webp |
1600 × 1100 | Valley landscape and route story |
lake.webp |
1600 × 1100 | Still-water landscape and route story |
hikers.webp |
1920 × 1200 | Introduction and company photograph |
To swap photographs, replace these local files and keep the names, or edit the manifest's src entries. Update every occurrence's alt text and caption to describe the new photograph. The lake is a landscape illustration; do not imply the set documents one exact itinerary.
In the GSAP Vault source repository, regenerate the derivatives with:
Code snippet omitted: it ships with the download.
That authoring command uses the repository's asset script and Sharp dependency; the deployed template does not need either. A buyer outside that repository can export their own WebP crops directly to assets/img/.
Photo credits
All source photographs are provided under the Pexels licence. The bundled files are resized and graded derivatives.
Accessibility and fallbacks
- Native links, range controls and departure disclosures support keyboard access, with visible focus rings.
- Landscape chapter buttons exist only in the enhanced desktop experience; other modes show every photograph.
- Reduced motion disables parallax and the pin, and makes route marker updates immediate.
- No-JS and blocked animation CDNs leave the complete document visible. The range is disabled and hidden until its handler is ready.
- Images have local files, explicit dimensions and descriptive alternatives. Above-the-fold photography is prioritised; later images load lazily.
- No touch gesture is captured for the hero. The native range supports touch without an unrelated page-wide gesture handler.
Smooth scrolling and cleanup
Set data-smooth="off" on <html> or use ?smooth=off to disable Lenis. Reduced motion also disables it. GSAP and Lenis share one ticker, and the refresh listener adopts the position restored by ScrollTrigger.
When unmounting this page in a client-side router, call window.gsapContext.revert() and then window.destroyLenis(). Context teardown reverts section animations and pins, removes stored event handlers, restores the static chapter documents and kills the route marker tween. Lenis teardown removes its ticker and refresh listener before destroying the instance.
Dependencies
- GSAP 3.12+ and ScrollTrigger; this page pins the current repository CDN release.
- Lenis, optional smooth scrolling.
- Google Fonts: Oswald and DM Sans.
- No framework, form provider, booking system or build runtime is needed for the static page.
Mobile navigation
Below 900px the header uses a native details menu. It works without JavaScript. With scripts available, choosing a link, clicking outside, pressing Escape or widening the viewport closes it. Escape returns focus to the toggle; choosing a section moves focus to that destination. Keep the desktop and mobile link lists in sync when renaming sections.
Expanding glass hero
The hero starts almost edge-to-edge with a 10–24px inset, rounded bottom corners and a light glass sheen over the photograph. A short pin (32% of a viewport on desktop, 22% on smaller or touch screens) expands it to the edges and straightens the lower corners before photograph/title parallax begins. The full-width .hero-shell owns the pin; the child owns the expanding margins. Reduced motion skips the pin and leaves the inset composition still. No query parameter is required.
Worked examples, the events and programmatic API, and the class reference ship with the download, alongside the full source.