File Structure
Norio 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-2.html:
{% extends "layouts/base.njk" %}
{% set title = "Home 02" %}
{% set description = "Norio — homepage variant 02." %}
{% set bodyClass = "page-home-2" %}
{% set headerName = "header-2" %}
{% set footerName = "footer-2" %}
{% block content %}
{% include "sections/hero/hero-2.njk" %}
{% include "sections/about/about-2.njk" %}
{% include "sections/projects/project-2.njk" %}
{% include "sections/cta/cta-1.njk" %}
{% endblock %}
Set headerName to header-2, header-3, or header-4 (default is header-1). Set footerName to footer-2 or footer-3 (default is footer-1). Optional page scripts go in {% block scripts %}.
Layout shell
src/layouts/base.njk renders the compiled document:
<!DOCTYPE html>
<html lang="en" data-color-scheme="{{ colorScheme }}">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ title }} — {{ site.name }}</title>
<link rel="icon" href="assets/imgs/favicon.svg" type="image/svg+xml">
<link href="https://fonts.googleapis.com/css2?family=Inter:opsz,wght@14..32,400;14..32,500;14..32,600;14..32,700&display=swap" rel="stylesheet">
</head>
<body class="at-magic-cursor {{ bodyClass }}">
<div id="magic-cursor" aria-hidden="true"><div id="ball"></div></div>
<!-- menu overlay + floating header toggle + bottom nav -->
<div id="smooth-wrapper">
<div id="smooth-content">
<!-- header-1 / header-2 / header-3 / header-4 -->
<main id="main-content">
{% block content %}{% endblock %}
</main>
<!-- footer-1 / footer-2 / footer-3 -->
</div>
</div>
<!-- vendors + Vite main.js -->
</body>
</html>
data-color-scheme is written only when the page sets colorScheme. #smooth-wrapper / #smooth-content are the GSAP ScrollSmoother roots. The magic cursor sits outside the smoother.
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-2">
<div class="container">
<h1 class="hero-2__title">…</h1>
<p class="hero-2__lead">…</p>
</div>
</section>
Matching styles live in src/assets/scss/sections/{group}/_{name}.scss and are forwarded from that folder’s _index.scss.
Scripts
src/partials/scripts.njk loads classic vendors from public/, then the Vite entry:
<script src="assets/js/vendors/jquery.odometer.min.js"></script>
<script src="assets/js/vendors/color-modes.js"></script>
<script type="module" src="/src/assets/js/main.js"></script>
main.js imports SCSS, registers GSAP plugins, creates ScrollSmoother, and boots section modules. Do not put inline <script>, <style>, or style="" in templates. Do not add Bootstrap or Tailwind classes — the convert-readiness guard will flag them.