htmlang
playground
@page htmlang Showcase @lang en -- Design tokens @let primary #3b82f6 @let accent #ec4899 @let ink #0f172a @let muted #64748b @let surface white @let bg #f8fafc @let radius 10 @let base 8 @let gap = $base * 2 -- Style presets @define card [ padding 24, background $surface, rounded $radius, border 1 #e2e8f0, dark:background #1e293b, dark:border 1 #334155 ] @mixin lift [ transition all 0.2s ease, hover:shadow 0 12px 24px rgba(0,0,0,0.08) ] -- Components (functions with parameters, defaults, and slots) @fn button $label $variant=primary @el [ padding 10 20, rounded 8, cursor pointer, bold, background if($variant == primary, $primary, transparent), color if($variant == primary, white, $primary), border 1 $primary, transition all 0.15s ease, hover:opacity 0.9, active:opacity 0.8 ] @text $label @fn feature $title $emoji @el [$card, ...$lift, spacing 10] @text [size 32] $emoji @text [bold, size 18, color $ink, dark:color #f1f5f9] $title @paragraph [color $muted, line-height 1.6] @children @fn stat $value $label @column [spacing 4, text-align center, padding 12] @text [bold, size 40, color $primary] $value @text [color $muted, size 12, text-transform uppercase, letter-spacing 2] $label -- Page @column [background $bg, dark:background #0f172a, min-height 100vh] -- Header @header [ padding 16 32, background $surface, dark:background #1e293b, border-bottom 1 #e2e8f0, dark:border-bottom 1 #334155 ] @row [center-y, max-width 1100, center-x, width 100%] @text [bold, size 18, color $ink, dark:color #f1f5f9] htmlang @el [width fill] @row [spacing 24] @link [color $muted, hover:color $primary] #docs Docs @link [color $muted, hover:color $primary] #blog Blog @link [color $muted, hover:color $primary] #github GitHub -- Hero @section [padding 80 32, max-width 900, center-x, text-align center, spacing 20] @el [ padding 6 14, rounded 999, background $primary|alpha:0.12, color $primary, bold, size 12, text-transform uppercase, letter-spacing 2, before:content "* " ] Built with htmlang @text [bold, size 56, color $ink, dark:color #f1f5f9, line-height 1.1] Layouts that just {@text [italic, color $primary] make sense}. @paragraph [max-width 600, center-x, color $muted, line-height 1.7, size 18] A minimalist DSL that compiles to a single static HTML file. No cascade, no JavaScript, no build chain. @row [center-x, spacing 12, wrap] @button [label Get Started] @button [label Star on GitHub, variant ghost] -- Stats (each iteration could go here too) @section [padding 24 32, max-width 800, center-x] @row [wrap, center-x, spacing 20] @stat [value 0kb, label JavaScript] @stat [value 1, label HTML File] @stat [value 100%, label Static] -- Features (grid layout) @section [padding 64 32, max-width 1100, center-x, spacing 24] @column [spacing 8, text-align center] @text [bold, size 32, color $ink, dark:color #f1f5f9] Why htmlang? @text [color $muted] Primitives over CSS quirks. @el [grid, grid-cols 3, gap $gap] @feature [title Composable, emoji X] Functions, mixins, and slots make components first-class. @feature [title Predictable, emoji Y] Flex-based layout - no cascade, no surprises. @feature [title Static, emoji Z] One file out. Deploy anywhere. Loads instantly. -- Quote (semantic blockquote + cite) @section [padding 32, max-width 720, center-x] @blockquote [ padding 24 32, background $surface, dark:background #1e293b, border-left 4 $primary, rounded $radius, italic, color $ink, dark:color #f1f5f9, line-height 1.7, size 18 ] "I want to lay out an interface, not argue with the cascade." @cite [color $muted, size 13, italic] - every frontend dev, eventually -- Team (each + destructuring) @section [padding 48 32, max-width 1100, center-x, spacing 16] @text [bold, size 24, color $ink, dark:color #f1f5f9] The team @row [wrap, spacing 12] @each $name, $role in Ada Engineer, Grace Architect, Linus Maintainer, Ken Researcher @column [$card, ...$lift, spacing 6, width 200, text-align center] @text [bold, color $ink, dark:color #f1f5f9] $name @text [color $muted, size 13] $role -- FAQ (native disclosure widget + inline elements) @section [padding 48 32, max-width 720, center-x, spacing 12] @text [bold, size 24, color $ink, dark:color #f1f5f9] FAQ @details [$card] @summary [bold, color $ink, dark:color #f1f5f9, cursor pointer] Does it support dark mode? @paragraph [color $muted, line-height 1.7] Yes - prefix any style with {@code [background $bg, padding 2 6, rounded 4, color $accent] dark:} and it generates a media query. @details [$card] @summary [bold, color $ink, dark:color #f1f5f9, cursor pointer] How do reusable components work? @paragraph [color $muted, line-height 1.7] Use {@code [background $bg, padding 2 6, rounded 4, color $accent] @fn} for parameters and {@code [background $bg, padding 2 6, rounded 4, color $accent] @children} as a slot. -- Native widgets (progress + meter) @section [padding 48 32, max-width 720, center-x, spacing 16] @text [bold, size 24, color $ink, dark:color #f1f5f9] Native widgets @column [$card, spacing 16] @column [spacing 6] @row [center-y, spacing 12] @text [color $ink, dark:color #f1f5f9] Coverage @el [width fill] @text [color $muted, size 13] 70% @progress [value 70, max 100, width 100%] @column [spacing 6] @text [color $ink, dark:color #f1f5f9] Battery @meter [value 6, min 0, max 10, low 3, high 8, width 100%] -- Footer (hr divider + breadcrumb) @hr [border-top 1 #e2e8f0, dark:border-top 1 #334155] @footer [padding 32, max-width 1100, center-x] @row [center-y, wrap, spacing 16, width 100%] @text [color $muted, size 13] Made with htmlang. @el [width fill] @breadcrumb [spacing 8] @link [color $muted, hover:color $primary] / Home @link [color $muted, hover:color $primary] /docs Docs @text [color $muted, size 13] v1.0
▶ Run (Ctrl+Enter)
Copy HTML
Share
Ready
preview