← The library

Lunaris

Marketing site for a city spa

Full template Members only Unlock the library

What it is

A spa site, complete: a full-screen hero, a logo marquee, a treatments accordion, animated figures, a three-step journey, a team carousel, reviews, memberships, an FAQ, a journal, a footer. One page, one HTML file.

The design follows that of a commercial template, of which only the photos have been kept. All the code has been rewritten: the original came to 192 kB of minified CSS, 159 opaque identifiers, 147 inline style= attributes, a proprietary animation engine and four external libraries — unreadable, and therefore useless for learning from. Here, every section is preceded by a comment saying what it is.

That's the whole point: this template isn't here to be admired, it's here to be read, broken and rebuilt.

What you change first

The colours — seven lines

Right at the top of assets/css/style.css:

--color-surface:   #fdf8f0;  /* page background, cream */
--color-surface-2: #ffffff;  /* cards, navigation bar */
--color-surface-3: #f0e8dc;  /* filled boxes */
--color-clay:      #6b4423;  /* brand colour: headings, dark sections */
--color-sand:      #d4c5b0;  /* dotted rules, borders */
--color-ink:       #33261a;  /* body text */

One thing to grasp before touching anything else: a custom property is substituted where it's declared, not where it's used. Redefining --color-ink further down isn't enough: --color-muted, which derives from it, keeps the value computed on :root. That's why the featured membership card redeclares both — and it's exactly the kind of bug that costs twenty minutes when you don't know the rule.

The name

Search for “Lunaris” in index.html. No CSS class carries the brand name: a find-and-replace can't break anything. The logo is an SVG plus a word written in HTML, not outlined text.

The sizes

The type scale is declared once, then redeclared at every breakpoint. So a heading never gets its own media query: you change --h2-size and the whole page follows.

The thirteen effects, and how they're built

All taken from the data of the original's animation engine (147 active triggers, 31 sequences), measured in the browser, then rewritten as readable CSS and JavaScript.

EffectWhereHow
Scroll reveal50 blocksIntersectionObserver, firing at 15% of the block, 1000 ms
Sideways reveal12 blockssame mechanism, 100 px horizontal translation
Rule that draws itself14 ruleswidth 0 → 100% in 1500 ms, in CSS alone
Counters3 figurestwo columns of digits in a one-digit window
Framed photo4 imageszoom 1.3 → 1 while a scrim slides out of the frame
Journey linestepsheight driven by the scroll, target measured on the dots
Sticky carouselteampanel sticky over 300 vh, track translated by the scroll
Marqueeslogos, opening hours59 px/s, copies counted on load, a loop with no jump
Buttonseverywherethe label rises, its copy arrives from below, the icon leaves diagonally
Treatments accordion4 cardsflex-basis animated: 40.8% for the open card, 28% for the others
Social iconsteamthe two states swap on hover, the disc fills
Dropdownsnavigationanimated height, chevron at 180°, keyboard and Escape handled
FAQquestions<details> native, animated height, delayed close

What you should know

  • No external requests. Self-hosted fonts, local photos, no CDN, no tracker. The original export made five.
  • Scroll reveals can't hide the content. The hidden state only exists once the JavaScript has run. Checked: with JavaScript switched off, the page renders 6,059 characters of text and no block is invisible.
  • Zero inline styles, zero inline scripts. The template honours the site's strict security policy, the very one the course teaches you not to weaken.
  • Accessibility: skip link, menu states announced, native FAQ, visible focus, decorations hidden from screen readers, animations switched off if the system asks.
  • Responsive checked at 390, 768, 1440 and 2560 px, with no horizontal overflow — the original had 9 px of it at 768 px.

What isn't perfect

Better said here than left for you to find out.

  • One flaw in the original has been fixed, not reproduced. Its logo marquee jumped back from −1169 px to −10 px while the pattern measures 1320 px: a 140 px jump on every lap. Here the loop covers exactly one pattern width, measured on load, at the same speed of 59 px/s. It's the only deliberate departure.
  • The page is 1.6% taller than the reference. A few sections breathe a little more. Nothing overlaps.
  • The links point to anchors on this page. The original is a multi-page site; here everything leads back to an existing section rather than to a 404.
  • The six partner logos are placeholders drawn for this template. To be replaced with real logos.
  • The photos come from the original template. The code is yours; for the visuals, check the licence or replace them. The fonts themselves are free to redistribute.

It's waiting for you in the library.

Lunaris comes with the subscription, alongside the other two templates, the sixteen components and the full course.

Immediate access · No commitment · Cancel in one click