Wit

A website built entirely in Wit

Build a self-styled, multi-section page as one Wit project — your own CSS and JS, no framework. The site is .wit files and one build command.

site.wit
theme.wit
script.wit
parts/nav.wit
parts/hero.wit

Step 1 — The root file

site.wit references the theme, the script and each section, then places them in order — the script last, so the DOM exists when it runs. None of these definitions has a ::body:: slot, so each use is one bare line.

reference ./theme.wit
reference ./script.wit
reference ./parts/nav.wit
reference ./parts/hero.wit

@stylesheet
@page_nav
@page_hero
@scripts

Step 2 — The design system

theme.wit holds one definition whose body is a raw @@style node — the whole stylesheet.

#stylesheet
@@style
:root { --bg: #f6f1e7; --accent: #8a2b39; }
:root.dark { --bg: #14110c; }
@media (max-width: 700px) { .hero { padding: 2rem; } }
style@@
stylesheet#

A raw node (@@name … name@@) is emitted verbatim: Wit never reads its body as markup, so CSS passes straight through. It still fills {{name}} from your definitions — color: {{accent}}; becomes the value of #accent: … !!.

Step 3 — Behaviour

script.wit puts the JavaScript in a frozen node, so nothing in it is touched.

#scripts
@@@script
var toggle = document.querySelector('.toggle');
if (toggle) {
  toggle.addEventListener('click', function () {
    document.documentElement.classList.toggle('dark');
  });
}
script@@@
scripts#

A frozen node (three @ signs) passes {{…}} through as well — use it for code with template syntax of its own.

Step 4 — The sections

Each file in parts/ exposes one definition built from core containers with a class parameter.

#page_hero
@header(class: hero)
(h1 Lighthouse Notes h1)
(p(class: lede) A field journal for keepers. p)
header@
page_hero#
#page_nav
@nav(class: top)
(a(href: #about) About a) (a(href: #log) Log a)
nav@
page_nav#

Put code samples in a frozen @@@pre node so Wit-looking source renders as text.

Step 5 — Build with your own CSS in charge

wit build site.wit -o site.html --raw

Result. A self-contained page: the <style> from theme.wit, the <nav class="top"> and <header class="hero"> sections, and the <script> from script.wit. Open it straight from disk.

Pitfalls

  • Use --raw. Without it the default theme CSS is inlined and competes with yours. --raw ships only a mechanical reset.
  • Raw versus frozen. A raw @@style fills {{name}}; a frozen @@@script does not. Pick frozen for code with braces you don't want touched.
  • A container section needs its close. If you give a section definition a ::body:: slot, every use that opens a block must end with its close tag.

Variations

Split the CSS across several raw style definitions; add a section with one file, one reference line and one use line — the same shape as a manuscript in chapters.

See also

Literal and raw nodes covers the raw and frozen forms; Rendering and styling covers themes and --raw.