File Structure

Rasuke pages are not assembled with Gulp @@include or Bootstrap navbar / offcanvas markup. A page file only extends the Nunjucks layout and includes sections. After npm run build, Vite writes flat HTML into dist/.

Compose a page

Example from src/pages/index-3.html:

{% extends "layouts/base.njk" %}

{% set title = "Home 3" %}
{% set description = site.description %}
{% set bodyClass = "page-home-3" %}
{% set colorScheme = "dark" %}
{% set headerPartial = "partials/header-4.njk" %}
{% set footerPartial = "partials/footer-3.njk" %}

{% block content %}
  {% include "sections/hero/hero-3.njk" %}
  {% include "sections/projects/projects-3.njk" %}
  {% include "sections/other/brands-1.njk" %}
  {% include "sections/other/fact-1.njk" %}
  {% include "sections/services/services-4.njk" %}
  {% include "sections/faqs/faqs-3.njk" %}
  {% include "sections/blog/blog-2.njk" %}
{% endblock %}
  • Set headerPartial to partials/header-2.njk, header-3.njk, or header-4.njk (default is header-1). Only header-1 pages also get the floating main-navigation pill.
  • Set footerPartial to partials/footer-2.njk or footer-3.njk (default is footer-1). Use partials/blank.njk to omit the chrome entirely (404, Showcase 1–4).
  • Set colorScheme = "dark" or "light" to pin a page; omit it to follow the OS. All shipped pages currently pin "dark".
  • Global toggles: {% set preloaderEnabled = false %}, cursorEnabled, transitionEnabled override src/data/preloader.json / cursor.json / transition.json per page. Most inner pages disable the preloader.
  • Optional page scripts go in {% block scripts %}; optional head markup in {% block head %}.
Layout shell

src/layouts/base.njk renders the compiled document:

<!DOCTYPE html>
<html lang="en" data-color-scheme="dark" data-transition-enter>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Home 3 — Rasuke</title>
  <link rel="icon" href="assets/imgs/favicon.svg" type="image/svg+xml">
  <!-- Host Grotesk + DM Sans + Bonheur Royale from Google Fonts.
       BDO Grotesk is licensed — add local @font-face when available. -->
</head>
<body class="page-home-3">
  <!-- page-transition (partials/page-transition.njk) -->
  <!-- preloader (partials/preloader.njk, homepages) -->
  <!-- offcanvas-menu -->
  <!-- main-navigation (header-1 pages only) -->
  <div id="smooth-wrapper">
    <div id="smooth-content">
      <!-- header-1 / header-2 / header-3 / header-4 -->
      <main id="main-content">…sections…</main>
      <!-- footer-1 / footer-2 / footer-3 -->
    </div>
  </div>
  <!-- custom cursor, back-to-top, scripts -->
</body>
</html>
  • data-color-scheme is written only when the page sets colorScheme.
  • data-transition-enter is written when the page transition is on and the preloader is off, so color-modes.js can park the page collapsed before first paint and the transition grows it back.
  • #smooth-wrapper / #smooth-content are the GSAP ScrollSmoother roots. The cursor, preloader, and transition overlays sit outside the smoother.
  • body.is-preloading is added while the preloader is active.
Section markup

Every design block is one section file. The first child of <section> must be exactly one .container (max-width 1500px). Classes are BEM-ish and unprefixed so they survive a later port:

<section class="hero-3">
  <div class="container">
    <h1 class="hero-3__title">…</h1>
    <p class="hero-3__lead">…</p>
  </div>
</section>

Matching styles live in src/assets/scss/sections/{group}/_{name}.scss and are forwarded from that folder's _index.scss. Content is usually looped from src/data/{name}.json. Section folders: hero (1–3), about (1–2), projects (1–3, listings 1–5, showcases 1–6), services (1–4), testimonials (1–2), team (1–3), blog (1–2), faqs (1–3), and other (page titles, pricing, contact, awards, brands, facts, CTA, 404…).

Scripts

src/partials/scripts.njk loads only the Vite entry in dev / production:

<script type="module" src="/src/assets/js/main.js"></script>

main.js imports the SCSS, registers GSAP plugins (ScrollTrigger, ScrollSmoother, ScrollToPlugin; SplitText is registered by the text modules), exposes window.gsap / window.THREE for classic consumers, creates ScrollSmoother, and boots every section module. Each module no-ops when its markup is absent. In the classic dist-html package the same entry is replaced by vendor UMD scripts + an IIFE bundle (see Development). Classic vendors that templates link directly — color-modes.js (in <head>, before first paint) and glightbox.min.css — live in public/.

Do not put inline <script>, <style>, or style="" in templates. Do not add Bootstrap or Tailwind classes — npm run lint:fse will flag them.