Wit

A website built entirely in Wit

Build a full, self-styled, multi-section landing page as one Wit project — you own every byte of CSS and JS, with no framework. The whole site is .wit files and one build command.

Step 1 — The root file

site.wit

references the theme, the script, and each section, then emits them in order — the script last so the DOM exists when it runs.

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

@stylesheet stylesheet@
@page_nav page_nav@
@page_hero page_hero@
@scripts scripts@

Step 2 — The design system

theme.wit

holds one definition whose body is a literal style node — the whole stylesheet, custom properties, dark-mode overrides, and media queries.

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

A double-fence literal node (@@) is emitted verbatim inside a style element: resolve and expand never re-parse or interpolate its body, so raw CSS passes straight through.

Step 3 — Behaviour

script.wit

puts the JavaScript in a frozen literal so the braces and template syntax pass through untouched.

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

A triple fence (@@@) freezes everything — needed so the JavaScript braces and any template syntax are not mistaken for Wit. A double fence still applies interpolation; a triple fence does not.

Step 4 — The sections

Each file in parts/ exposes one definition — page_hero, page_features — built from core containers (div, section, nav, header) with class parameters. Verbatim code samples go in a frozen pre node so Wit-looking source renders as text, not markup.

Step 5 — Build with your own CSS in charge

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

A self-contained page: your styles from theme.wit, the assembled sections, and your script from script.wit. The theme toggle switches dark and light. Open the file straight from disk — there is no server and no build step beyond this command.

Pitfalls

  • Use --raw. Without it the default theme CSS is inlined and competes with yours. --raw ships only a mechanical reset, so your rules win.
  • Blank line after a leading comment. A comment as the first line of a container body, with no blank line after it, collapses the following blocks into one paragraph.
  • Freeze code that contains braces. Use the triple fence for any JavaScript or code with curly braces or template syntax you don't want touched; the double fence still interpolates.

Variations

Split the CSS across several literal style definitions; add a section by writing one file, one reference line, and one emit line — the same additive shape as a multi-file manuscript.

See also

Architecture

explains the pipeline the literal nodes ride through; Write a custom renderer goes further down the stack.