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.witreferences 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.witputs 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 --rawResult. 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.--rawships 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
Architectureexplains the pipeline the literal nodes ride through; Write a custom renderer goes further down the stack.