@@ -1,41 +1,330 @@
1+-- A comprehensive tour of htmlang: layout, style, components, and control flow.
12@page htmlang Demo
2−@let primary #3b82f6
3−@let gap 20
3+@lang en
4+@meta description A one-page tour of htmlang.
5+@og title htmlang
6+@og type website
47
5−-- reusable card with hover effect
6−@fn card $title
7− @el [padding 20, background white, rounded 8, border 1 #e5e7eb, hover:border 1 $primary, transition all 0.15s ease, cursor pointer]
8− @text [bold] $title
8+-- Design tokens become both $vars and CSS custom properties
9+@theme
10+ primary #3b82f6
11+ ink #0f172a
12+ muted #64748b
13+ subtle #f8fafc
14+
15+-- Computed @let with arithmetic
16+@let base 8
17+@let gap = $base * 2
18+@let gutter = $gap + $base
19+
20+-- Reusable attribute bundle
21+@define card [
22+ padding $gap,
23+ background white,
24+ rounded $base,
25+ border 1 #e5e7eb,
26+ shadow 0 1px 3px rgba(0,0,0,0.05)
27+]
28+
29+-- Composable style group (used with spread)
30+@mixin interactive [
31+ cursor pointer,
32+ hover:shadow 0 4px 12px rgba(0,0,0,0.08),
33+ transition all 0.2s ease
34+]
35+
36+-- Keyframes using attribute syntax
37+@keyframes fade-up
38+ from [opacity 0, transform translateY(8px)]
39+ to [opacity 1, transform translateY(0)]
40+
41+-- Raw HTML escape hatch
42+@raw """
43+<noscript><style>.needs-js{display:none}</style></noscript>
44+"""
45+
46+-- Component with default parameter + @children slot
47+@fn card $title $icon=◆
48+ @article [$card, ...$interactive, animate fade-up 0.3s ease]
49+ @row [spacing 10, align-items center]
50+ @text [size 20, color $primary] $icon
51+ @text [bold, size 16, color $ink] $title
952 @children
1053
11−-- page layout function
12−@fn page-section $title
13− @column [spacing 10]
14− @text [bold, size 24, color #333] $title
54+-- Component that wraps children in a titled section (function + slot)
55+@fn titled $title
56+ @section [spacing 12, padding-y $base]
57+ @text [bold, size 22, color $ink] $title
1558 @children
1659
17−@column [max-width 800, center-x, padding 40, spacing $gap]
18− @row [spacing $gap]
19− @column [width fill, spacing 10]
20− @text [bold, size 32] Welcome to htmlang
21− @paragraph
22− A minimalist layout language that compiles to
23− {@text [bold, color $primary] static HTML}.
24− @image [width 80, height 80, rounded 40, alt "A stock photo"] https://picsum.photos/80
25−
26− -- cards using @fn with hover
27− @page-section [title Features]
28− @row [wrap, spacing 10]
29− @card [title Simple]
30− Write layouts without CSS
31− @card [title Fast]
32− Compiles to a single HTML file
33− @card [title Minimal]
34− No JavaScript required
35−
36− -- footer with hover button
37− @row [spacing 10]
38− @el [padding 16, background $primary, hover:background #2563eb, active:background #1d4ed8, rounded 8, transition all 0.15s ease, cursor pointer] > @link https://github.com
39− @text [color white, bold] Get Started
40− @el [width fill]
41− @text [color #888] © 2026
60+-- Top-level layout
61+@column [
62+ max-width 960,
63+ center-x,
64+ padding 32,
65+ spacing $gutter,
66+ background white,
67+ dark:background #0b1220,
68+ dark:color #e2e8f0
69+]
70+
71+ -- Header: nav + hero
72+ @header [spacing $base]
73+ @nav [spacing 6, color $muted, size 13]
74+ @row [spacing 6, align-items center]
75+ @link [color $muted] / Home
76+ @text /
77+ @link [color $muted] /demos Demos
78+ @text /
79+ @text [color $ink] htmlang
80+
81+ @row [spacing $gap, align-items center]
82+ @column [width fill, spacing 6]
83+ @text [bold, size 40, color $ink, dark:color white] Welcome to htmlang
84+ @paragraph [line-height 1.6, color $muted]
85+ A minimalist layout language that compiles to
86+ {@text [bold, color $primary] static HTML} — no JS, no build step.
87+ Visit the {@link [color $primary, underline] https://github.com repo} for more.
88+ @image [width 72, height 72, rounded 36, alt "Avatar"] https://picsum.photos/72
89+
90+ @hr [border-top 1 #e5e7eb]
91+
92+ -- Feature grid using @card + @titled components
93+ @titled [title Features]
94+ @row [wrap, gap $base]
95+ @card [title Simple, icon ✦]
96+ Write layouts without CSS classes.
97+ @card [title Fast, icon ⚡]
98+ Compiles to a single self-contained HTML file.
99+ @card [title Minimal, icon ○]
100+ Zero runtime JavaScript by default.
101+ @card [title Typed]
102+ LSP with diagnostics and go-to-definition.
103+
104+ -- Typography showcase: inline elements, blockquote, code
105+ @titled [title Typography]
106+ @paragraph [line-height 1.7]
107+ A quick brown fox jumps over {@text [bold] the lazy} {@text [italic] dog}.
108+ Press {@kbd [
109+ padding 2 6, background #f1f5f9, rounded 4,
110+ font monospace, size 13
111+ ] Ctrl+K} to search. {@mark [background #fef08a] Highlighted} uses mark.
112+ {@abbr [title HyperText Markup Language + language] htmlang} is an abbreviation.
113+
114+ @blockquote [
115+ padding-inline-start $gap, border-left 3 $primary,
116+ color $muted, italic
117+ ]
118+ Layout is code. Style is code. Everything should compose.
119+ @cite — Anonymous
120+
121+ @pre [
122+ background #0f172a, color #e2e8f0,
123+ padding 16, rounded 8, font monospace, size 13,
124+ overflow-x auto
125+ ]
126+ @raw """
127+@fn button $label
128+ @el [padding 12, background blue]
129+ @text $label
130+"""
131+
132+ -- Control flow: @each, @else, @repeat, @for, @match, if()
133+ @titled [title Control flow]
134+ @column [spacing 6]
135+ @each $name, $role in Alice Engineer, Bob Designer, Carol PM
136+ @row [spacing 10, align-items baseline]
137+ @text [bold, min-width 80] $name
138+ @text [color $muted] $role
139+
140+ -- @each ... @else fallback for empty list
141+ @let nothing ""
142+ @each $x in $nothing
143+ @text $x
144+ @else
145+ @text [color $muted, italic, data-state $nothing] (Nothing — @each ... @else fallback)
146+
147+ -- @repeat
148+ @row [spacing 6]
149+ @repeat 6
150+ @el [width 18, height 18, rounded 9, background $primary, opacity 0.4]
151+
152+ -- @for range
153+ @row [spacing 4]
154+ @for $i in 1..6
155+ @el [
156+ width 24, height 24, rounded 4,
157+ background $primary, color white,
158+ text-align center, size 12, bold, line-height 24
159+ ]
160+ $i
161+
162+ -- @if / @else if / @else (with @assert to verify at compile time)
163+ @let count 3
164+ @assert $count == 3
165+ @row [spacing 6, align-items center]
166+ @text [bold, min-width 64] Count:
167+ @if $count == 0
168+ @text [color $muted] Empty
169+ @else if $count == 1
170+ @text [color $primary] Exactly one
171+ @else
172+ @text [color $primary, bold] $count items
173+
174+ -- @match
175+ @let status ready
176+ @match $status
177+ @case pending
178+ @text [color #f59e0b] Pending…
179+ @case ready
180+ @text [color #10b981, bold] ✓ Ready
181+ @case error
182+ @text [color #ef4444] Error
183+ @default
184+ @text Unknown
185+
186+ -- Conditional attribute value + before: pseudo-element
187+ @let emphasized true
188+ @el [
189+ padding 12, rounded 6,
190+ background if($emphasized, $primary, #e5e7eb),
191+ color if($emphasized, white, $ink),
192+ before:content "→ ", before:bold
193+ ]
194+ Conditional styling via {@code if(cond, a, b)}.
195+
196+ -- Forms + pseudo-states
197+ @titled [title Forms]
198+ @form [spacing 10, max-width 420] /subscribe
199+ @label [bold, size 13, for email] Email
200+ @input [
201+ id email, type email, name email,
202+ placeholder you@example.com, required,
203+ padding 10, border 1 #e5e7eb, rounded 6,
204+ focus:border 1 $primary,
205+ valid:border 1 #10b981,
206+ invalid:border 1 #ef4444,
207+ transition border 0.15s ease
208+ ]
209+ @label [bold, size 13, for role] Role
210+ @select [id role, name role, padding 10, border 1 #e5e7eb, rounded 6]
211+ @option [value dev] Developer
212+ @option [value designer] Designer
213+ @option [value other] Other
214+ @label [bold, size 13, for msg] Message
215+ @textarea [
216+ id msg, name msg, rows 3,
217+ padding 10, border 1 #e5e7eb, rounded 6
218+ ]
219+ @row [spacing 8]
220+ @button [
221+ type submit,
222+ padding 10 16, background $primary, color white, bold,
223+ rounded 6, border 0,
224+ hover:background $primary|darken:10,
225+ active:background $primary|darken:20,
226+ transition background 0.15s ease,
227+ cursor pointer
228+ ] Subscribe
229+ @button [
230+ type reset,
231+ padding 10 16, background white,
232+ border 1 #e5e7eb, rounded 6, cursor pointer
233+ ] Reset
234+ @progress [value 60, max 100]
235+
236+ -- Lists and tables
237+ @titled [title Data]
238+ @row [gap $gap, wrap]
239+ @column [width fill, spacing $base, min-width 240]
240+ @text [bold] Unordered
241+ @list [spacing 4]
242+ @item Composable with @each
243+ @item Indent to nest children
244+ @item Bold list items work too
245+ @text [bold] Ordered
246+ @list [ordered]
247+ @item First
248+ @item Second
249+ @item Third
250+
251+ @column [width fill, spacing $base, min-width 240]
252+ @text [bold] Table
253+ @table
254+ @thead
255+ @tr
256+ @th [text-align left, padding 8] Item
257+ @th [text-align right, padding 8] Qty
258+ @tbody
259+ @tr
260+ @td [padding 8, border-top 1 #e5e7eb] Widgets
261+ @td [padding 8, border-top 1 #e5e7eb, text-align right] 12
262+ @tr
263+ @td [padding 8, border-top 1 #e5e7eb] Gadgets
264+ @td [padding 8, border-top 1 #e5e7eb, text-align right] 7
265+
266+ @figure [spacing 6]
267+ @image [alt "A random placeholder", rounded 8] https://picsum.photos/640/200
268+ @figcaption [color $muted, size 13, text-align center]
269+ A placeholder image.
270+
271+ -- Disclosure + named grid areas
272+ @titled [title Disclosure + grid areas]
273+ @details [padding 12, border 1 #e5e7eb, rounded 6, background $subtle]
274+ @summary [bold, cursor pointer] What is htmlang?
275+ @paragraph [color $muted, line-height 1.6, padding-block-start 6]
276+ htmlang is a layout-first language that compiles to a single,
277+ self-contained HTML file with embedded CSS.
278+
279+ -- Implicit @el via bare [attrs] line
280+ [
281+ grid,
282+ grid-template-columns 1fr 2fr,
283+ grid-template-areas "h h" "s m" "f f",
284+ gap $base,
285+ padding $base, background $subtle, rounded 8
286+ ]
287+ @el [grid-area h, padding 10, background $primary, color white, rounded 6, text-align center]
288+ Header
289+ @el [grid-area s, padding 10, background white, rounded 6, border 1 #e5e7eb]
290+ Sidebar
291+ @el [grid-area m, padding 10, background white, rounded 6, border 1 #e5e7eb]
292+ Main
293+ @el [grid-area f, padding 10, background $ink, color white, rounded 6, text-align center]
294+ Footer
295+
296+ -- Misc: address, time, meter
297+ @titled [title Misc]
298+ @address [spacing 4, font-style normal]
299+ @text [bold] htmlang HQ
300+ @text 123 Flexbox Avenue
301+ @link [color $primary] mailto:hi@htmlang.dev hi@htmlang.dev
302+ @row [spacing 10, align-items center]
303+ @text [size 13, color $muted] Published
304+ @time [datetime 2026-04-16, size 13] April 16 2026
305+ @row [spacing 10, align-items center]
306+ @text [size 13, color $muted] Confidence
307+ @meter [value 8, min 0, max 10, low 3, high 7] 8/10
308+
309+ -- Footer: hover/active button, visited link, print-hidden
310+ @footer [
311+ padding-block-start $gutter, margin-block-start $gutter,
312+ border-top 1 #e5e7eb, spacing $base,
313+ print:display none
314+ ]
315+ @row [spacing $base, align-items center]
316+ @el [
317+ padding 12 20, background $primary, color white, bold, rounded 8,
318+ hover:background $primary|darken:10,
319+ active:background $primary|darken:20,
320+ transition all 0.15s ease,
321+ cursor pointer
322+ ] > @link https://github.com
323+ Get Started
324+ @link [
325+ color $primary,
326+ visited:color #8b5cf6,
327+ hover:underline
328+ ] https://github.com Browse source
329+ @el [width fill]
330+ @text [color $muted, size 13] © 2026 htmlang