on master help sign in
One default container: remove @column

@el and @column produced the same flex column, and every semantic container is a column too; only @row differs. @el is the container. height fill, center-x and align-left/right now treat any column parent alike, fixing height fill inside @el (it was height: 100%).

commita276f8d9e9488c6ad57c211d61f76434170f49b9 authoriko <mail@iko.soy> dateSat 26 Sep 2026, 03:37 (2 weeks ago) parent81f89d2
55 files changed+139−137
DESIGN.md+4−5 README.md+2−2 crates/htmlang-core/src/ast.rs+8−4 crates/htmlang-core/src/codegen.rs+7−7 crates/htmlang-core/src/parser.rs+7−7 editors/vscode/snippets/htmlang.json+3−3 examples/blog.hl+1−1 examples/demo.hl+5−5 examples/docs.hl+1−1 examples/landing.hl+3−3 src/bin/htmlang_lsp/completion.rs+1−1 src/bin/htmlang_lsp/docs.rs+1−2 src/fmt.rs+1−1 src/upgrade.rs+4−4 tests/regressions.rs+2−2 tests/snapshots.rs+11−11 tests/snapshots/alignment.hl+1−1 tests/snapshots/animate_shorthand.hl+1−1 tests/snapshots/animations.hl+1−1 tests/snapshots/attributes.hl+1−1 tests/snapshots/basic_elements.hl+1−1 tests/snapshots/computed_let.hl+1−1 tests/snapshots/convert_basic.hl+1−1 tests/snapshots/css_shorthands.hl+1−1 tests/snapshots/css_units.hl+1−1 tests/snapshots/css_vars.hl+1−1 tests/snapshots/each_else.hl+2−2 tests/snapshots/each_step.hl+2−2 tests/snapshots/extra_css.hl+1−1 tests/snapshots/form_elements.hl+1−1 tests/snapshots/fragment.hl+1−1 tests/snapshots/functions.hl+1−1 tests/snapshots/has_pseudo.hl+1−1 tests/snapshots/manifest_directive.hl+1−1 tests/snapshots/markdown_block.hl+1−1 tests/snapshots/meta_head.hl+1−1 tests/snapshots/new_css_properties_2.hl+1−1 tests/snapshots/new_css_properties_3.hl+1−1 tests/snapshots/new_directives.hl+1−1 tests/snapshots/new_elements_5.hl+1−1 tests/snapshots/nth_pseudo.hl+1−1 tests/snapshots/pseudo_elements.hl+1−1 tests/snapshots/raw_html.hl+1−1 tests/snapshots/scope_css.hl+1−1 tests/snapshots/scroll_driven_animations.hl+1−1 tests/snapshots/selection_pseudo.hl+1−1 tests/snapshots/sizing.hl+1−1 tests/snapshots/starting_style.hl+1−1 tests/snapshots/stress_deeply_nested.hl+12−12 tests/snapshots/stress_large.hl+27−27 tests/snapshots/stress_large.html+1−1 tests/snapshots/translations_i18n.hl+1−1 tests/snapshots/variable_filters.hl+1−1 tests/snapshots/variables_defines.hl+1−1 tests/snapshots/view_transitions.hl+1−1
DESIGN.md+4−5
@@ -91,13 +91,12 @@ verbatim too (a `--` line in them is not a comment).
9191## Elements
9292
9393Layout elements set up flexbox; the rest map to the HTML element of the same
94−name.
94+name. Every container lays its children out in a column, except `@row`.
9595
9696| Element | Output | Purpose |
9797|---|---|---|
9898| `@row` | div, flex row | Horizontal layout |
99−| `@column` | div, flex column | Vertical layout |
100−| `@el` | div, flex column | Generic container |
99+| `@el` | div, flex column | The container: children laid out top to bottom |
101100| `@grid` | div, grid | Grid container (use `grid-cols`) |
102101| `@stack` | div, position relative | Children layered on top of each other |
103102| `@in-front` / `@behind` | div, absolute | Overlay layers filling the parent (see below) |
@@ -413,7 +412,7 @@ with `@slot name` (named blocks, with default content) and `@children`
413412-- layout.hl
414413@let layout
415414 @page My Site
416− @column [max-width 800, center-x]
415+ @el [max-width 800, center-x]
417416 @slot header
418417 @text Default header
419418 @children
@@ -485,7 +484,7 @@ removed form with its replacement.
485484| `@og KEY VALUE` | `@meta og:KEY VALUE` |
486485| `@assert`, `@warn`, `@debug`, `@log` | Nothing (the lines are removed) |
487486| `@defer` | Its content, directly |
488−| `@col`, `@p`, `@img`, `@li`, `@btn`, `@ul`, `@divider`, `@opt` | `@column`, `@paragraph`, `@image`, `@item`, `@button`, `@list`, `@hr`, `@option` |
487+| `@col`, `@p`, `@img`, `@li`, `@btn`, `@ul`, `@divider`, `@opt` | `@el`, `@paragraph`, `@image`, `@item`, `@button`, `@list`, `@hr`, `@option` |
489488| `type email`, `id main` (HTML attributes written as styles) | `type=email`, `id=main` |
490489| `skeleton`, `no-scrollbar`, `gradient A B` | `$skeleton`, `$no-scrollbar`, `background linear-gradient(A, B)` |
491490| `@tooltip TEXT` | `@tooltip [tip TEXT] TEXT` |
README.md+2−2
@@ -15,7 +15,7 @@ A minimalist layout language inspired by [elm-ui](https://package.elm-lang.org/p
1515 @text [font-weight bold] $title
1616 @children
1717
18−@column [max-width 800, center-x, padding 40, spacing 20]
18+@el [max-width 800, center-x, padding 40, spacing 20]
1919 @text [font-weight bold, font-size 32] Hello
2020
2121 @paragraph
@@ -69,7 +69,7 @@ formatting.
6969
7070## Language tour
7171
72−Elements are laid out with `@row`, `@column` and `@el`; `@text`, `@paragraph`,
72+Elements are laid out with `@el` (a column) and `@row`; `@text`, `@paragraph`,
7373`@link` and `@image` hold content, and every other HTML element is available by
7474name (`@nav`, `@section`, `@table`, `@input`, ...).
7575
crates/htmlang-core/src/ast.rs+8−4
@@ -61,7 +61,6 @@ pub struct Attribute {
6161pub enum ElementKind {
6262 // Layout and text: the core of the language
6363 Row,
64− Column,
6564 El,
6665 Text,
6766 Paragraph,
@@ -82,7 +81,6 @@ impl ElementKind {
8281 pub fn name(&self) -> &str {
8382 match self {
8483 ElementKind::Row => "row",
85− ElementKind::Column => "column",
8684 ElementKind::El => "el",
8785 ElementKind::Text => "text",
8886 ElementKind::Paragraph => "paragraph",
@@ -103,6 +101,13 @@ impl ElementKind {
103101 }
104102 }
105103
104+ /// Does this element lay its children out in a flex column (`@el` and
105+ /// the semantic containers)?
106+ pub fn is_column(&self) -> bool {
107+ matches!(self, ElementKind::El)
108+ || self.spec().is_some_and(|spec| spec.css.contains("flex-direction:column"))
109+ }
110+
106111 /// Is this the table element named `name` (e.g. `"main"`)?
107112 pub fn is_tag(&self, name: &str) -> bool {
108113 self.spec().is_some_and(|spec| spec.name == name)
@@ -112,7 +117,6 @@ impl ElementKind {
112117 pub fn from_name(name: &str) -> Option<ElementKind> {
113118 Some(match name {
114119 "row" => ElementKind::Row,
115− "column" => ElementKind::Column,
116120 "el" => ElementKind::El,
117121 "text" => ElementKind::Text,
118122 "paragraph" => ElementKind::Paragraph,
@@ -129,7 +133,7 @@ impl ElementKind {
129133 /// Every element name, for suggestions and completions.
130134 pub fn all_names() -> impl Iterator<Item = &'static str> {
131135 [
132− "row", "column", "el", "text", "paragraph", "link", "image", "script", "fragment",
136+ "row", "el", "text", "paragraph", "link", "image", "script", "fragment",
133137 "children", "slot",
134138 ]
135139 .into_iter()
crates/htmlang-core/src/codegen.rs+7−7
@@ -972,7 +972,7 @@ fn generate_node(
972972 Node::Text(segments) => {
973973 let needs_wrap = matches!(
974974 parent_kind,
975− Some(ElementKind::Row | ElementKind::Column | ElementKind::El)
975+ Some(ElementKind::Row | ElementKind::El)
976976 ) || parent_kind
977977 .and_then(ElementKind::spec)
978978 .is_some_and(|spec| spec.wraps_text);
@@ -1144,7 +1144,7 @@ fn generate_element(
11441144 }
11451145
11461146 let tag = match &elem.kind {
1147− ElementKind::Row | ElementKind::Column | ElementKind::El => "div",
1147+ ElementKind::Row | ElementKind::El => "div",
11481148 ElementKind::Text => "span",
11491149 ElementKind::Paragraph => "p",
11501150 ElementKind::Link => "a",
@@ -1698,7 +1698,7 @@ fn attrs_to_css(
16981698 }
16991699 match kind {
17001700 ElementKind::Row => css.push_str("display:flex;flex-direction:row;"),
1701− ElementKind::Column | ElementKind::El => css.push_str(FLEX_COLUMN),
1701+ ElementKind::El => css.push_str(FLEX_COLUMN),
17021702 ElementKind::Paragraph => css.push_str("margin:0;"),
17031703 ElementKind::Tag(spec) => css.push_str(spec.css),
17041704 _ => {}
@@ -1777,7 +1777,7 @@ fn attrs_to_css(
17771777 if let Some(v) = val {
17781778 match v {
17791779 "fill" => match parent_kind {
1780− Some(ElementKind::Column) => {
1780+ Some(parent) if parent.is_column() => {
17811781 push_css(&mut css, "flex", "1");
17821782 push_css(&mut css, "min-height", "0");
17831783 }
@@ -1811,7 +1811,7 @@ fn attrs_to_css(
18111811
18121812 // Alignment
18131813 "center-x" => match parent_kind {
1814− Some(ElementKind::Column) | Some(ElementKind::El) => {
1814+ Some(parent) if parent.is_column() => {
18151815 push_css(&mut css, "align-self", "center");
18161816 }
18171817 _ => {
@@ -1827,13 +1827,13 @@ fn attrs_to_css(
18271827 }
18281828 },
18291829 "align-left" => match parent_kind {
1830− Some(ElementKind::Column) | Some(ElementKind::El) => {
1830+ Some(parent) if parent.is_column() => {
18311831 push_css(&mut css, "align-self", "flex-start");
18321832 }
18331833 _ => push_css(&mut css, "margin-right", "auto"),
18341834 },
18351835 "align-right" => match parent_kind {
1836− Some(ElementKind::Column) | Some(ElementKind::El) => {
1836+ Some(parent) if parent.is_column() => {
18371837 push_css(&mut css, "align-self", "flex-end");
18381838 }
18391839 _ => push_css(&mut css, "margin-left", "auto"),
crates/htmlang-core/src/parser.rs+7−7
@@ -1508,7 +1508,7 @@ const REMOVED_SYNTAX: &[(&str, &str)] = &[
15081508 "@component",
15091509 "use `@let`: an `@style` block in a function body is scoped to it",
15101510 ),
1511− ("@col", "use `@column`"),
1511+ ("@col", "use `@el`"),
15121512 ("@p", "use `@paragraph`"),
15131513 ("@img", "use `@image`"),
15141514 ("@li", "use `@item`"),
@@ -2661,7 +2661,7 @@ fn split_if_args(input: &str) -> Vec<&str> {
26612661// Post-parse validation (context-dependent warnings)
26622662// ---------------------------------------------------------------------------
26632663
2664−/// Attributes that only make sense on container elements (@row, @column, @el).
2664+/// Attributes that only make sense on container elements (@row, @el, @el).
26652665const CONTAINER_ONLY_ATTRS: &[&str] = &[
26662666 "spacing",
26672667 "gap",
@@ -2678,7 +2678,7 @@ fn element_kind_name(kind: &ElementKind) -> String {
26782678}
26792679
26802680fn is_container(kind: &ElementKind) -> bool {
2681− matches!(kind, ElementKind::Row | ElementKind::Column | ElementKind::El)
2681+ matches!(kind, ElementKind::Row | ElementKind::El)
26822682 || kind.spec().is_some_and(|spec| spec.container)
26832683}
26842684
@@ -2704,7 +2704,7 @@ pub fn lint(nodes: &[Node]) -> Vec<Diagnostic> {
27042704 depth
27052705 ));
27062706 }
2707− if matches!(elem.kind, ElementKind::Row | ElementKind::Column | ElementKind::El)
2707+ if matches!(elem.kind, ElementKind::Row | ElementKind::El)
27082708 && elem.children.is_empty()
27092709 {
27102710 warn(format!("empty container (@{}) has no children", elem.kind.name()));
@@ -2745,12 +2745,12 @@ fn validate_tree(
27452745 }
27462746 if base == "height"
27472747 && attr.value.as_deref() == Some("fill")
2748− && !matches!(parent_kind, Some(ElementKind::Column))
2748+ && !parent_kind.is_some_and(ElementKind::is_column)
27492749 {
27502750 diagnostics.push(Diagnostic {
27512751 line: elem.line_num,
27522752 column: None,
2753− message: "'height fill' works best inside @column; using 100% as fallback"
2753+ message: "'height fill' works best inside @el; using 100% as fallback"
27542754 .to_string(),
27552755 severity: Severity::Warning,
27562756 source_line: None,
@@ -2763,7 +2763,7 @@ fn validate_tree(
27632763 line: elem.line_num,
27642764 column: None,
27652765 message: format!(
2766− "'{}' has no effect on {} (only works on @row, @column, @el)",
2766+ "'{}' has no effect on {} (only works on @row, @el, @el)",
27672767 base,
27682768 element_kind_name(&elem.kind)
27692769 ),
editors/vscode/snippets/htmlang.json+3−3
@@ -5,7 +5,7 @@
55 "@page ${1:My Page}",
66 "@let primary ${2:#3b82f6}",
77 "",
8− "@column [max-width ${3:800}, center-x, padding ${4:40}, spacing ${5:20}]",
8+ "@el [max-width ${3:800}, center-x, padding ${4:40}, spacing ${5:20}]",
99 " $0"
1010 ],
1111 "description": "Page boilerplate with title, variables, and layout"
@@ -27,7 +27,7 @@
2727 "prefix": "@let-slots",
2828 "body": [
2929 "@let ${1:layout} \\$${2:title}",
30− " @column [${3:max-width 800, center-x, padding 40}]",
30+ " @el [${3:max-width 800, center-x, padding 40}]",
3131 " @slot ${4:header}",
3232 " @text [font-weight bold, font-size 32] \\$$2",
3333 " @slot ${5:content}",
@@ -145,7 +145,7 @@
145145 "Hero section": {
146146 "prefix": "@hero",
147147 "body": [
148− "@column [center-x, center-y, min-height ${1:80vh}, padding ${2:40}, spacing ${3:20}]",
148+ "@el [center-x, center-y, min-height ${1:80vh}, padding ${2:40}, spacing ${3:20}]",
149149 " @text [font-weight bold, font-size ${4:48}, text-align center] ${5:Hero Title}",
150150 " @paragraph [max-width ${6:600}, text-align center, color ${7:#666}, line-height 1.6]",
151151 " ${8:Hero description text}",
examples/blog.hl+1−1
@@ -22,7 +22,7 @@
2222 @link [color $primary, font-weight bold] /posts/$title
2323 Read more
2424
25−@column [max-width 720, center-x, padding 40, spacing 32]
25+@el [max-width 720, center-x, padding 40, spacing 32]
2626 @header [spacing 8]
2727 @text [font-weight bold, font-size 36, color $ink] My Blog
2828 @text [color $muted] Thoughts on static HTML, layout, and nice defaults.
examples/demo.hl+5−5
@@ -62,7 +62,7 @@
6262 @children
6363
6464-- Top-level layout
65−@column [
65+@el [
6666 max-width 960,
6767 center-x,
6868 padding 32,
@@ -83,7 +83,7 @@
8383 @text [color $ink] htmlang
8484
8585 @row [spacing $gap, align-items center]
86− @column [width fill, spacing 6]
86+ @el [width fill, spacing 6]
8787 @text [font-weight bold, font-size 40, color $ink, dark:color white] Welcome to htmlang
8888 @paragraph [line-height 1.6, color $muted]
8989 A minimalist layout language that compiles to
@@ -134,7 +134,7 @@
134134
135135 -- Control flow: @each, @else, @match, if()
136136 @titled [title Control flow]
137− @column [spacing 6]
137+ @el [spacing 6]
138138 @data $team [
139139 {"name": "Alice", "role": "Engineer"},
140140 {"name": "Bob", "role": "Designer"},
@@ -242,7 +242,7 @@
242242 -- Lists and tables
243243 @titled [title Data]
244244 @row [gap $gap, wrap]
245− @column [width fill, spacing $base, min-width 240]
245+ @el [width fill, spacing $base, min-width 240]
246246 @text [font-weight bold] Unordered
247247 @list [spacing 4, list-style disc, padding-inline-start 20]
248248 @item [display list-item] Composable with @each
@@ -254,7 +254,7 @@
254254 @item [display list-item] Second
255255 @item [display list-item] Third
256256
257− @column [width fill, spacing $base, min-width 240]
257+ @el [width fill, spacing $base, min-width 240]
258258 @text [font-weight bold] Table
259259 @table
260260 @thead
examples/docs.hl+1−1
@@ -50,7 +50,7 @@
5050
5151 @pre [background $code-bg, padding 16, border-radius 8, overflow-x auto]
5252 @page Hello
53− @column [padding 40, spacing 16]
53+ @el [padding 40, spacing 16]
5454 @text [font-weight bold, font-size 32] Hi there
5555
5656 @paragraph [color $ink, line-height 1.7]
examples/landing.hl+3−3
@@ -6,12 +6,12 @@
66@let bg-subtle #f8fafc
77
88@let feature $title $body
9− @column [padding 24, background white, border-radius 12, border 1 solid #e2e8f0, spacing 8]
9+ @el [padding 24, background white, border-radius 12, border 1 solid #e2e8f0, spacing 8]
1010 @text [font-weight bold, font-size 18, color $ink] $title
1111 @paragraph [color $muted, line-height 1.6]
1212 $body
1313
14−@column [spacing 0]
14+@el [spacing 0]
1515 -- Hero
1616 @section [
1717 padding 80,
@@ -40,7 +40,7 @@
4040
4141 -- Features
4242 @section [padding 80, padding-inline 24, max-width 1100, center-x, spacing 40]
43− @column [spacing 8, text-align center]
43+ @el [spacing 8, text-align center]
4444 @text [font-weight bold, font-size 32, color $ink] Everything you need
4545 @text [color $muted] Opinionated where it matters, flexible where it counts.
4646 @row [wrap, gap 20]
src/bin/htmlang_lsp/completion.rs+1−1
@@ -160,7 +160,7 @@ fn snippet_completions(range: Range) -> Vec<CompletionItem> {
160160 (
161161 "responsive layout",
162162 "Centered responsive column layout",
163− "@column [max-width 800, center-x, padding 40, spacing 20]",
163+ "@el [max-width 800, center-x, padding 40, spacing 20]",
164164 ),
165165 (
166166 "nav bar",
src/bin/htmlang_lsp/docs.rs+1−2
@@ -34,8 +34,7 @@ const fn doc(name: &'static str, summary: &'static str, usage: &'static str) ->
3434/// from their row in `TAGS`.
3535pub(crate) const ELEMENTS: &[Doc] = &[
3636 doc("row", "Horizontal layout: a flex row.", "@row [spacing 10]\n @text A\n @text B"),
37− doc("column", "Vertical layout: a flex column.", "@column [spacing 10]\n @text A\n @text B"),
38− doc("el", "Generic container (a flex column).", "@el [padding 20, background white]\n Content"),
37+ doc("el", "The container: a flex column (only `@row` lays out horizontally).", "@el [padding 20, background white]\n Content"),
3938 doc("text", "Styled inline text (`<span>`).", "@text [font-weight bold, font-size 24] Hello"),
4039 doc(
4140 "paragraph",
src/fmt.rs+1−1
@@ -510,7 +510,7 @@ mod tests {
510510
511511 #[test]
512512 fn bracket_in_text_does_not_join_lines() {
513− let src = "@column\n Use [ to open a list\n @text [font-weight bold] Second\n";
513+ let src = "@el\n Use [ to open a list\n @text [font-weight bold] Second\n";
514514 assert_eq!(format(src), src);
515515 }
516516
src/upgrade.rs+4−4
@@ -15,7 +15,7 @@ pub struct Upgrade {
1515
1616/// Element aliases and their canonical names.
1717const ELEMENT_ALIASES: &[(&str, &str)] = &[
18− ("col", "column"),
18+ ("col", "el"),
1919 ("p", "paragraph"),
2020 ("img", "image"),
2121 ("li", "item"),
@@ -1698,7 +1698,7 @@ mod tests {
16981698
16991699 #[test]
17001700 fn element_aliases() {
1701− assert_eq!(up("@col [padding 4]\n @p hi"), "@column [padding 4]\n @paragraph hi");
1701+ assert_eq!(up("@col [padding 4]\n @p hi"), "@el [padding 4]\n @paragraph hi");
17021702 assert_eq!(up("@el > @btn Go"), "@el > @button Go");
17031703 assert_eq!(up("Say {@img a.png} now"), "Say {@image a.png} now");
17041704 // Not aliases: @page, @paragraph, text mentioning @p
@@ -1992,8 +1992,8 @@ mod tests {
19921992 );
19931993 assert_eq!(super::layout_function_name("parts/base.hl"), "base-layout");
19941994 assert_eq!(
1995− super::convert_layout("@page Site\n@column\n @children\n", "layout").unwrap(),
1996− "@let layout\n @page Site\n @column\n @children\n"
1995+ super::convert_layout("@page Site\n@el\n @children\n", "layout").unwrap(),
1996+ "@let layout\n @page Site\n @el\n @children\n"
19971997 );
19981998 assert!(super::convert_layout("@let layout\n x\n", "layout").is_none());
19991999 assert_eq!(
tests/regressions.rs+2−2
@@ -158,7 +158,7 @@ fn source_map_uses_real_output_lines() {
158158
159159#[test]
160160fn bracket_in_text_does_not_join_lines() {
161− let out = compile("@column\n Use [ to open a list\n @text [font-weight bold] Second\n @text Third");
161+ let out = compile("@el\n Use [ to open a list\n @text [font-weight bold] Second\n @text Third");
162162 assert!(out.contains("Use [ to open a list"), "{}", out);
163163 assert!(out.contains(">Second<"), "{}", out);
164164 assert!(out.contains(">Third<"), "{}", out);
@@ -236,7 +236,7 @@ fn quoted_font_stack_is_one_attribute() {
236236
237237#[test]
238238fn diagnostic_column_includes_indentation() {
239− let result = parser::parse("@let name x\n@column\n Hello $nmae");
239+ let result = parser::parse("@let name x\n@el\n Hello $nmae");
240240 let d = result
241241 .diagnostics
242242 .iter()
tests/snapshots.rs+11−11
@@ -309,7 +309,7 @@ fn error_opacity_range() {
309309
310310#[test]
311311fn warning_fill_outside_row() {
312− let diags = parse_diagnostics("@column\n @el [width fill]");
312+ let diags = parse_diagnostics("@el\n @el [width fill]");
313313 assert!(
314314 diags
315315 .iter()
@@ -730,7 +730,7 @@ fn removed_aliases_point_to_upgrade() {
730730 for (src, replacement) in [
731731 ("@li Works", "@item"),
732732 ("@divider", "@hr"),
733− ("@el > @col x", "@column"),
733+ ("@el > @col x", "@el"),
734734 ("Say {@img a.png}", "@image"),
735735 ] {
736736 let diags = parse_diagnostics(src);
@@ -1135,11 +1135,11 @@ fn warning_controls_on_non_media() {
11351135
11361136#[test]
11371137fn fmt_normalizes_indentation() {
1138− let input = "@row\n @column\n @text hello\n @column\n @text world";
1138+ let input = "@row\n @el\n @text hello\n @el\n @text world";
11391139 let formatted = htmlang::fmt::format(input);
11401140 assert_eq!(
11411141 formatted,
1142− "@row\n @column\n @text hello\n @column\n @text world\n"
1142+ "@row\n @el\n @text hello\n @el\n @text world\n"
11431143 );
11441144}
11451145
@@ -1621,7 +1621,7 @@ fn even_generates_pseudo() {
16211621
16221622#[test]
16231623fn fragment_no_wrapper() {
1624− let output = compile("@page T\n@column\n @fragment\n @text A\n @text B");
1624+ let output = compile("@page T\n@el\n @fragment\n @text A\n @text B");
16251625 // Fragment should NOT add any div wrapper
16261626 assert!(!output.contains("<div class=\"_1\"><span"));
16271627 // But children should still be present
@@ -1946,13 +1946,13 @@ fn css_writing_mode() {
19461946
19471947#[test]
19481948fn css_column_count() {
1949− let output = compile("@page T\n@column [column-count 3]");
1949+ let output = compile("@page T\n@el [column-count 3]");
19501950 assert!(output.contains("column-count:3"));
19511951}
19521952
19531953#[test]
19541954fn css_column_gap() {
1955− let output = compile("@page T\n@column [column-gap 20]");
1955+ let output = compile("@page T\n@el [column-gap 20]");
19561956 assert!(output.contains("column-gap:20px"));
19571957}
19581958
@@ -3323,7 +3323,7 @@ fn output_contains_layer_wrapping() {
33233323#[test]
33243324fn fn_named_slots() {
33253325 let output = compile(
3326− "@let layout\n @column\n @slot header\n Default Header\n @slot content\n@layout\n @slot header\n Custom Header\n @slot content\n Page body",
3326+ "@let layout\n @el\n @slot header\n Default Header\n @slot content\n@layout\n @slot header\n Custom Header\n @slot content\n Page body",
33273327 );
33283328 assert!(
33293329 output.contains("Custom Header"),
@@ -3345,7 +3345,7 @@ fn fn_named_slots() {
33453345#[test]
33463346fn fn_named_slot_default() {
33473347 let output = compile(
3348− "@let layout\n @column\n @slot header\n Default Header\n @slot content\n@layout\n @slot content\n Only content",
3348+ "@let layout\n @el\n @slot header\n Default Header\n @slot content\n@layout\n @slot content\n Only content",
33493349 );
33503350 assert!(
33513351 output.contains("Default Header"),
@@ -3848,7 +3848,7 @@ fn switch_with_attrs() {
38483848
38493849#[test]
38503850fn minified_output_is_smaller() {
3851− let input = "@page Test\n@column [padding 20]\n @text [font-weight bold] Hello World\n @paragraph\n Some text here\n";
3851+ let input = "@page Test\n@el [padding 20]\n @text [font-weight bold] Hello World\n @paragraph\n Some text here\n";
38523852 let result = htmlang::parser::parse(input);
38533853 let normal = htmlang::codegen::generate(&result.document);
38543854 let minified = htmlang::codegen::generate_minified(&result.document);
@@ -3863,7 +3863,7 @@ fn minified_output_is_smaller() {
38633863
38643864#[test]
38653865fn minified_strips_comments() {
3866− let input = "@page Test\n@column\n @text Hello\n";
3866+ let input = "@page Test\n@el\n @text Hello\n";
38673867 let result = htmlang::parser::parse(input);
38683868 let dev = htmlang::codegen::generate_dev(&result.document);
38693869 let minified = htmlang::codegen::generate_minified(&result.document);
tests/snapshots/alignment.hl+1−1
@@ -1,5 +1,5 @@
11@page Alignment
2−@column [height 400]
2+@el [height 400]
33 @el [center-x] Centered X
44 @el [center-y] Centered Y
55 @el [align-left] Left
tests/snapshots/animate_shorthand.hl+1−1
@@ -9,7 +9,7 @@
99 from { transform: translateY(20px); opacity: 0; }
1010 to { transform: translateY(0); opacity: 1; }
1111 }
12−@column [spacing 20, padding 20]
12+@el [spacing 20, padding 20]
1313 @el [animation fade-in 0.3s ease, padding 20]
1414 Faded in
1515 @el [animation slide-up 0.5s ease-out, padding 20, background #e5e7eb]
tests/snapshots/animations.hl+1−1
@@ -10,7 +10,7 @@
1010 0%{transform:translateY(20px);opacity:0}100%{transform:translateY(0);opacity:1}
1111 }
1212
13−@column [spacing 20]
13+@el [spacing 20]
1414 @el [animation fade-in 0.3s ease]
1515 @text Fading in
1616 @el [animation slide-up 0.5s ease-out]
tests/snapshots/attributes.hl+1−1
@@ -3,6 +3,6 @@
33 @text [font-weight bold, font-style italic, text-decoration underline, font-size 16, font-family monospace] Styled
44@row [wrap, column-gap 10, row-gap 5, spacing 8]
55 @el [min-width 50, max-width 200, min-height 30, max-height 100]
6−@column [overflow hidden, position relative, z-index 10]
6+@el [overflow hidden, position relative, z-index 10]
77 @text [text-align center, line-height 1.5] Aligned
88@el [box-shadow 0 2px 4px rgba(0,0,0,0.1), transition all 0.2s, cursor pointer]
tests/snapshots/basic_elements.hl+1−1
@@ -2,7 +2,7 @@
22@row [spacing 10]
33 @text [font-weight bold] Hello
44 @text World
5−@column [spacing 5]
5+@el [spacing 5]
66 @el [padding 10]
77 @text Inner
88@paragraph
tests/snapshots/computed_let.hl+1−1
@@ -2,6 +2,6 @@
22@let base 16
33@let large = $base * 2
44@let gap = $base + 4
5−@column [spacing $gap, padding 20]
5+@el [spacing $gap, padding 20]
66 @text [font-size $base] Base size
77 @text [font-size $large] Large size
tests/snapshots/convert_basic.hl+1−1
@@ -1,4 +1,4 @@
11@page Test
2−@column
2+@el
33 @paragraph
44 Hello world
tests/snapshots/css_shorthands.hl+1−1
@@ -1,6 +1,6 @@
11@page CSS Shorthands
22
3−@column [spacing 20]
3+@el [spacing 20]
44 -- Truncate
55 @text [max-width 200, $truncate] This text will be truncated with an ellipsis
66
tests/snapshots/css_units.hl+1−1
@@ -1,5 +1,5 @@
11@page CSS Units
2−@column [padding 2rem, spacing 1.5em]
2+@el [padding 2rem, spacing 1.5em]
33 @el [width 50%, height 100vh, max-width 80ch]
44 @text [font-size 1.2rem] Hello
55 @el [padding 10 2rem, border-radius 0.5rem]
tests/snapshots/css_vars.hl+1−1
@@ -3,7 +3,7 @@
33@let --spacing 20
44@let --radius 8
55
6−@column [spacing $--spacing]
6+@el [spacing $--spacing]
77 @el [background var(--primary), border-radius $--radius, padding $--spacing]
88 @text [color white] Using CSS vars
99 @el [border 1 solid var(--primary), border-radius $--radius, padding $--spacing]
tests/snapshots/each_else.hl+2−2
@@ -2,7 +2,7 @@
22
33-- Empty list triggers @else (variable resolves to empty string)
44@let empty ""
5−@column [spacing 10]
5+@el [spacing 10]
66 @each $item in $empty
77 @text $item
88 @else
@@ -10,7 +10,7 @@
1010
1111-- Non-empty list renders loop, not @else
1212@let fruits apple, banana
13−@column [spacing 10]
13+@el [spacing 10]
1414 @each $fruit in $fruits
1515 @text $fruit
1616 @else
tests/snapshots/each_step.hl+2−2
@@ -1,7 +1,7 @@
11@page Each Step
22
33-- Basic step
4−@column [spacing 4]
4+@el [spacing 4]
55 @each $i in 0..20 step 5
66 @text Value: $i
77
@@ -12,6 +12,6 @@
1212 @text [color white, font-size 12] $n
1313
1414-- Reverse range with step
15−@column [spacing 4]
15+@el [spacing 4]
1616 @each $i in 10..1 step 2
1717 @text Countdown: $i
tests/snapshots/extra_css.hl+1−1
@@ -1,4 +1,4 @@
1−@column [spacing 20]
1+@el [spacing 20]
22 @el [display none]
33 Hidden
44 @el [visibility hidden]
tests/snapshots/form_elements.hl+1−1
@@ -3,7 +3,7 @@
33 @button [type=submit] Click me
44 @input [type=text, placeholder=Enter name, name=username]
55 @input [type=email, required, disabled]
6−@column [spacing 5]
6+@el [spacing 5]
77 @label [for=bio] Biography
88 @textarea [name=bio, rows=4] Default text
99@select [name=color]
tests/snapshots/fragment.hl+1−1
@@ -1,6 +1,6 @@
11@page Fragment Test
22
3−@column [spacing 10]
3+@el [spacing 10]
44 @fragment
55 @text First
66 @text Second
tests/snapshots/functions.hl+1−1
@@ -5,7 +5,7 @@
55 @children
66
77@let wrapper
8− @column [spacing 10]
8+ @el [spacing 10]
99 @children
1010
1111@wrapper
tests/snapshots/has_pseudo.hl+1−1
@@ -1,5 +1,5 @@
11@page Has Pseudo
2−@column [spacing 20, padding 20]
2+@el [spacing 20, padding 20]
33 @el [padding 20, background white, has(.active):background #dbeafe, has(img):padding 0]
44 Content
55 @el [border 1 solid #e5e7eb, has(.selected):border 2 solid #3b82f6, border-radius 8]
tests/snapshots/manifest_directive.hl+1−1
@@ -3,5 +3,5 @@
33@head
44 <link rel="manifest" href="manifest.json">
55
6−@column [padding 20]
6+@el [padding 20]
77 @text Hello
tests/snapshots/markdown_block.hl+1−1
@@ -1,6 +1,6 @@
11@page Markdown Test
22
3−@column [padding 20]
3+@el [padding 20]
44 @markdown
55 # Hello World
66 This is a **bold** paragraph with *italic* text.
tests/snapshots/meta_head.hl+1−1
@@ -5,5 +5,5 @@
55@head
66 <link rel="icon" href="favicon.ico">
77
8−@column [padding 20]
8+@el [padding 20]
99 @text Hello
tests/snapshots/new_css_properties_2.hl+1−1
@@ -12,7 +12,7 @@
1212@el [writing-mode vertical-rl]
1313 @text Vertical text
1414
15−@column [column-count 3, column-gap 20]
15+@el [column-count 3, column-gap 20]
1616 @text Multi-column layout content here
1717
1818@paragraph [text-indent 2em]
tests/snapshots/new_css_properties_3.hl+1−1
@@ -1,6 +1,6 @@
11@page New CSS Properties 3
22
3−@column [spacing 20]
3+@el [spacing 20]
44 @text [font-weight 600] Semi-bold text
55 @text [font-style oblique] Oblique text
66 @text [text-wrap balance, font-size 32] A heading that wraps nicely
tests/snapshots/new_directives.hl+1−1
@@ -16,5 +16,5 @@
1616 }
1717 </script>
1818
19−@column [spacing 10]
19+@el [spacing 10]
2020 @text [font-family Inter] Hello with custom fonts
tests/snapshots/new_elements_5.hl+1−1
@@ -1,6 +1,6 @@
11@page New Elements 5
22
3−@column [spacing 20]
3+@el [spacing 20]
44 -- Avatar
55 @avatar [width 48, height 48, background #e5e7eb]
66 @text AB
tests/snapshots/nth_pseudo.hl+1−1
@@ -1,7 +1,7 @@
11@page Nth Pseudo
22
33-- nth-child styling
4−@column [spacing 4]
4+@el [spacing 4]
55 @each $i in 1..5
66 @el [padding 8, nth:3:background #3b82f6, nth:3:color white]
77 @text Item $i
tests/snapshots/pseudo_elements.hl+1−1
@@ -1,6 +1,6 @@
11@page Pseudo Elements
22
3−@column [spacing 20]
3+@el [spacing 20]
44 @el [before:content "→ ", before:color red]
55 Item with arrow prefix
66 @el [after:content " ✓", after:color green]
tests/snapshots/raw_html.hl+1−1
@@ -1,5 +1,5 @@
11@page Raw HTML
2−@column [spacing 10]
2+@el [spacing 10]
33 @text Before raw
44 @raw <div class="custom">Raw HTML content</div>
55 @text After raw
tests/snapshots/scope_css.hl+1−1
@@ -6,5 +6,5 @@
66 .body { color: #333; }
77 }
88
9−@column [padding 20]
9+@el [padding 20]
1010 @text Hello
tests/snapshots/scroll_driven_animations.hl+1−1
@@ -6,6 +6,6 @@
66 to { opacity: 1; }
77 }
88
9−@column [padding 20]
9+@el [padding 20]
1010 @el [animation fade-in linear, animation-timeline scroll(), animation-range entry 0% cover 50%]
1111 @text Animated on scroll
tests/snapshots/selection_pseudo.hl+1−1
@@ -5,6 +5,6 @@
55 Select this text to see custom selection colors.
66
77-- Multiple elements with selection
8−@column [spacing 16]
8+@el [spacing 16]
99 @text [selection:background #ef4444, selection:color white] Red selection
1010 @text [selection:background #22c55e, selection:color black] Green selection
tests/snapshots/sizing.hl+1−1
@@ -3,6 +3,6 @@
33 @el [width fill, background #eee] Fill width
44 @el [width 100, background #ddd] Fixed 100
55 @el [width shrink, background #ccc] Shrink
6−@column [width 400]
6+@el [width 400]
77 @el [height fill, background #eee] Fill height
88 @el [height 50, background #ddd] Fixed 50
tests/snapshots/starting_style.hl+1−1
@@ -5,5 +5,5 @@
55 .fade-in { opacity: 0; }
66 }
77
8−@column [padding 20]
8+@el [padding 20]
99 @text [opacity 1, transition opacity 0.3s ease] Hello
tests/snapshots/stress_deeply_nested.hl+12−12
@@ -14,17 +14,17 @@
1414 @text [font-size 13, color #64748b] $label
1515 @children
1616
17−@column [spacing 20, padding 24]
17+@el [spacing 20, padding 24]
1818
1919 @el [background #f0f9ff, border-radius 12, padding 20, border 1 solid #bae6fd]
2020 @text [font-weight bold, font-size 20, color #0369a1] Level 1 - App Shell
2121 @row [spacing 16, margin-top 16]
2222 @el [background white, border-radius 8, padding 16, border 1 solid $--border, width fill]
2323 @text [font-weight bold, font-size 16, color #1e293b] Level 2 - Sidebar
24− @column [spacing 8, margin-top 12]
24+ @el [spacing 8, margin-top 12]
2525 @el [background #f1f5f9, border-radius 6, padding 12]
2626 @text [font-size 14, color #475569] Level 3 - Nav Group
27− @column [spacing 4, margin-top 8]
27+ @el [spacing 4, margin-top 8]
2828 @el [padding 8 12, hover:background #e2e8f0, border-radius 4, transition all 0.15s]
2929 @text [font-size 13, color #64748b] Level 4 - Nav Item
3030 @row [spacing 6, margin-top 4, align-items center]
@@ -50,14 +50,14 @@
5050
5151 @el [background #f1f5f9, border-radius 6, padding 12]
5252 @text [font-size 14, color #475569] Level 3 - Second Group
53− @column [spacing 4, margin-top 8]
53+ @el [spacing 4, margin-top 8]
5454 @each $item in Settings,Profile,Security
5555 @el [padding 8 12, hover:background #e2e8f0, border-radius 4]
5656 @text [font-size 13, color #64748b] $item
5757
5858 @el [background white, border-radius 8, padding 16, border 1 solid $--border, width fill]
5959 @text [font-weight bold, font-size 16, color #1e293b] Level 2 - Main Content
60− @column [spacing 12, margin-top 12]
60+ @el [spacing 12, margin-top 12]
6161 @deep-card [title Level 3 - Dashboard Card]
6262 @inner-panel [label Level 4 - Chart Area]
6363 @row [spacing 8, margin-top 8]
@@ -85,7 +85,7 @@
8585
8686 @deep-card [title Level 3 - Form Card]
8787 @inner-panel [label Level 4 - Form Section]
88− @column [spacing 8, margin-top 8]
88+ @el [spacing 8, margin-top 8]
8989 @el [padding 8, border 1 solid $--border, border-radius 4]
9090 @text [font-size 12, color #64748b, margin-bottom 4] Level 5 - Field Group
9191 @input [type=text, placeholder=Name, padding 6 10, border-radius 4, border 1 solid $--border, width fill]
@@ -105,12 +105,12 @@
105105
106106 @deep-card [title Level 3 - Nested Lists Card]
107107 @inner-panel [label Level 4 - Category Browser]
108− @column [spacing 6, margin-top 8]
108+ @el [spacing 6, margin-top 8]
109109 @let top-categories Electronics,Clothing,Books
110110 @each $cat in $top-categories
111111 @el [padding 8, border 1 solid $--border, border-radius 4, hover:background #f8fafc]
112112 @text [font-size 14, font-weight bold, color #1e293b] Level 5 - $cat
113− @column [spacing 4, margin-top 6, margin-left 12]
113+ @el [spacing 4, margin-top 6, margin-left 12]
114114 @el [padding 6, background #f8fafc, border-radius 4]
115115 @row [spacing 8, align-items center]
116116 @el [width 8, height 8, border-radius 2, background $--primary]
@@ -122,10 +122,10 @@
122122
123123 @el [background #fefce8, border-radius 12, padding 20, border 1 solid #fde68a, margin-top 20]
124124 @text [font-weight bold, font-size 20, color #854d0e] Level 1 - Settings Panel
125− @column [spacing 12, margin-top 16]
125+ @el [spacing 12, margin-top 16]
126126 @el [background white, border-radius 8, padding 16, border 1 solid $--border]
127127 @text [font-weight bold, font-size 16, color #1e293b] Level 2 - Account Settings
128− @column [spacing 8, margin-top 12]
128+ @el [spacing 8, margin-top 12]
129129 @el [background #f8fafc, border-radius 6, padding 12]
130130 @text [font-size 14, color #475569] Level 3 - Profile Section
131131 @el [margin-top 8, padding 10, border 1 solid $--border, border-radius 6]
@@ -141,7 +141,7 @@
141141
142142 @el [background #f8fafc, border-radius 6, padding 12]
143143 @text [font-size 14, color #475569] Level 3 - Preferences
144− @column [spacing 6, margin-top 8]
144+ @el [spacing 6, margin-top 8]
145145 @each $pref in Language,Timezone,Currency
146146 @row [spacing 8, align-items center, padding 6 8, border 1 solid $--border, border-radius 4]
147147 @text [font-size 13, color #1e293b, width fill] Level 4 - $pref
@@ -150,7 +150,7 @@
150150
151151 @el [background white, border-radius 8, padding 16, border 1 solid $--border]
152152 @text [font-weight bold, font-size 16, color #1e293b] Level 2 - Notification Preferences
153− @column [spacing 6, margin-top 12]
153+ @el [spacing 6, margin-top 12]
154154 @let channels Email,Push,SMS,Slack
155155 @each $channel in $channels
156156 @row [spacing 8, align-items center, padding 8, border-bottom 1 solid $--border]
tests/snapshots/stress_large.hl+27−27
@@ -121,18 +121,18 @@
121121
122122@row [spacing 0, min-height 100vh]
123123
124− @column [width 260, background white, dark:background #0f172a, border-right 1 solid $--border, dark:border-right 1 solid #1e293b, padding $--gap, spacing $--gap-sm]
124+ @el [width 260, background white, dark:background #0f172a, border-right 1 solid $--border, dark:border-right 1 solid #1e293b, padding $--gap, spacing $--gap-sm]
125125
126126 @row [spacing 12, padding 8, align-items center]
127127 @avatar [initials HL, size 36]
128− @column [spacing 2]
128+ @el [spacing 2]
129129 @text [font-weight bold, font-size 16, color $--dark, dark:color white] htmlang
130130 @text [font-size 12, color $--gray] Dashboard v2.0
131131
132132 @divider
133133
134134 @sidebar-section [title Navigation]
135− @column [spacing 2]
135+ @el [spacing 2]
136136 @nav-link [url /dashboard, label Dashboard, active true]
137137 @nav-link [url /analytics, label Analytics]
138138 @nav-link [url /projects, label Projects]
@@ -143,13 +143,13 @@
143143 @nav-link [url /settings, label Settings]
144144
145145 @sidebar-section [title Favorites]
146− @column [spacing 2]
146+ @el [spacing 2]
147147 @nav-link [url /project/alpha, label Project Alpha]
148148 @nav-link [url /project/beta, label Project Beta]
149149 @nav-link [url /reports/q4, label Q4 Reports]
150150
151151 @sidebar-section [title Shortcuts]
152− @column [spacing 4]
152+ @el [spacing 4]
153153 @row [spacing 8, align-items center]
154154 @el [width 6, height 6, border-radius 50%, background $--secondary]
155155 @text [font-size 13, color $--gray] Online (12)
@@ -163,15 +163,15 @@
163163 @el [margin-top auto, padding 12, background #f1f5f9, dark:background #1e293b, border-radius $--radius]
164164 @row [spacing 8, align-items center]
165165 @avatar [initials JD, size 28]
166− @column [spacing 0]
166+ @el [spacing 0]
167167 @text [font-size 13, font-weight bold, color $--dark, dark:color white] Jane Doe
168168 @text [font-size 11, color $--gray] jane@example.com
169169
170− @column [width fill, background $--light, dark:background #0f172a]
170+ @el [width fill, background $--light, dark:background #0f172a]
171171
172172 @header [padding 12 24, background white, dark:background #0f172a, border-bottom 1 solid $--border, dark:border-bottom 1 solid #1e293b]
173173 @row [spacing 16, align-items center]
174− @column [spacing 2]
174+ @el [spacing 2]
175175 @row [spacing 8]
176176 @breadcrumb-item [url /, label Home]
177177 @breadcrumb-item [url /dashboard, label Dashboard, is-last true]
@@ -205,21 +205,21 @@
205205 @el [width fill, height $height%, background $--primary, hover:background #2563eb, border-radius 4 4 0 0, transition all 0.2s, min-width 20]
206206
207207 @card [title Activity Feed]
208− @column [spacing 12, margin-top 12]
208+ @el [spacing 12, margin-top 12]
209209 @each $member in $team-members
210210 @row [spacing 12, align-items center, padding 8, hover:background #f8fafc, dark:hover:background #1e293b, border-radius 6]
211211 @avatar [initials $member, size 32]
212− @column [spacing 2, width fill]
212+ @el [spacing 2, width fill]
213213 @text [font-size 14, font-weight bold, color $--dark, dark:color white] $member
214214 @text [font-size 12, color $--gray] Updated project files
215215 @text [font-size 11, color $--gray] 2h ago
216216
217217 @row [spacing $--gap, margin-top $--gap-lg, sm:flex-direction column, lg:flex-direction row]
218218
219− @column [width fill, spacing $--gap]
219+ @el [width fill, spacing $--gap]
220220
221221 @card [title Project Status]
222− @column [spacing 0, margin-top 12]
222+ @el [spacing 0, margin-top 12]
223223 @row [spacing 0, padding 8 16, background #f8fafc, dark:background #0f172a, border-bottom 1 solid $--border]
224224 @el [width 200]
225225 @text [font-weight bold, font-size 12, color $--gray, text-transform uppercase] Project
@@ -237,16 +237,16 @@
237237 @table-row [col1 Project Epsilon, col2 On Hold, col3 45%, col4 Feb 28 2026]
238238
239239 @card [title Progress Breakdown]
240− @column [spacing 12, margin-top 12]
240+ @el [spacing 12, margin-top 12]
241241 @each $project in $projects
242− @column [spacing 4]
242+ @el [spacing 4]
243243 @row [spacing 0]
244244 @text [font-size 13, color $--dark, dark:color white, width fill] $project
245245 @text [font-size 13, color $--gray] 67%
246246 @progress-bar [percent 67, color var(--primary)]
247247
248248 @card [title Recent Activity Log]
249− @column [spacing 8, margin-top 12]
249+ @el [spacing 8, margin-top 12]
250250 @let log-entries Deployed v2.3.1 to production,Merged feature/auth-redesign,Closed issue #482: Login timeout,Updated CI/CD pipeline config,Added unit tests for payment module,Reviewed PR #156: API refactor,Fixed memory leak in worker pool,Released hotfix 2.3.2
251251 @each $entry, $i in $log-entries
252252 @row [spacing 12, padding 8 12, align-items center]
@@ -255,21 +255,21 @@
255255 @text [font-size 14, color $--dark, dark:color white, width fill] $entry
256256 @text [font-size 11, color $--gray] just now
257257
258− @column [width 340, sm:width fill, spacing $--gap]
258+ @el [width 340, sm:width fill, spacing $--gap]
259259
260260 @card [title Quick Actions]
261− @column [spacing 8, margin-top 12]
261+ @el [spacing 8, margin-top 12]
262262 @icon-button [label New Project, color var(--primary)]
263263 @icon-button [label Create Report, color var(--secondary)]
264264 @icon-button [label Invite Member, color var(--accent)]
265265 @icon-button [label View Backlog, color var(--gray)]
266266
267267 @card [title Team Members]
268− @column [spacing 8, margin-top 12]
268+ @el [spacing 8, margin-top 12]
269269 @each $member in $team-members
270270 @row [spacing 10, align-items center, padding 6 8, hover:background #f1f5f9, dark:hover:background #1e293b, border-radius 6, transition all 0.15s]
271271 @avatar [initials $member, size 28]
272− @column [spacing 0, width fill]
272+ @el [spacing 0, width fill]
273273 @text [font-size 13, font-weight bold, color $--dark, dark:color white] $member
274274 @text [font-size 11, color $--gray] Developer
275275 @el [width 8, height 8, border-radius 50%, background $--secondary]
@@ -290,7 +290,7 @@
290290 @tag [label api]
291291
292292 @card [title Notifications]
293− @column [spacing 0, margin-top 12]
293+ @el [spacing 0, margin-top 12]
294294 @let notifications New deployment completed,PR review requested,Build failed on staging,Meeting in 30 minutes,Subscription renewal due
295295 @each $note in $notifications
296296 @row [spacing 10, padding 10 12, border-bottom 1 solid $--border, dark:border-bottom 1 solid #334155, align-items center]
@@ -299,7 +299,7 @@
299299 @text [font-size 11, color $--gray] now
300300
301301 @card [title Settings]
302− @column [spacing 12, margin-top 12]
302+ @el [spacing 12, margin-top 12]
303303 @row [spacing 0, align-items center]
304304 @text [font-size 14, color $--dark, dark:color white, width fill] Dark Mode
305305 @toggle [checked true]
@@ -315,7 +315,7 @@
315315
316316 @el [margin-top $--gap-lg]
317317 @card [title Data Table]
318− @column [spacing 0, margin-top 12]
318+ @el [spacing 0, margin-top 12]
319319 @row [spacing 16, margin-bottom 12, align-items center]
320320 @input [type=search, placeholder=Filter results..., padding 8 12, border-radius 6, border 1 solid $--border, width 240]
321321 @el [width fill]
@@ -363,33 +363,33 @@
363363
364364 @footer [padding $--gap-lg 24, background white, dark:background #0f172a, border-top 1 solid $--border, dark:border-top 1 solid #1e293b]
365365 @row [spacing $--gap-lg, sm:flex-direction column, lg:flex-direction row]
366− @column [spacing 8, width fill]
366+ @el [spacing 8, width fill]
367367 @text [font-weight bold, font-size 14, color $--dark, dark:color white] htmlang Dashboard
368368 @text [font-size 12, color $--gray] Built with htmlang - a declarative HTML language
369369 @text [font-size 11, color $--gray] Copyright 2025 htmlang contributors
370370
371− @column [spacing 4]
371+ @el [spacing 4]
372372 @text [font-weight bold, font-size 12, color $--gray, text-transform uppercase, margin-bottom 4] Product
373373 @link [color $--gray, hover:color $--primary, font-size 13] /features Features
374374 @link [color $--gray, hover:color $--primary, font-size 13] /pricing Pricing
375375 @link [color $--gray, hover:color $--primary, font-size 13] /changelog Changelog
376376 @link [color $--gray, hover:color $--primary, font-size 13] /roadmap Roadmap
377377
378− @column [spacing 4]
378+ @el [spacing 4]
379379 @text [font-weight bold, font-size 12, color $--gray, text-transform uppercase, margin-bottom 4] Resources
380380 @link [color $--gray, hover:color $--primary, font-size 13] /docs Documentation
381381 @link [color $--gray, hover:color $--primary, font-size 13] /api API Reference
382382 @link [color $--gray, hover:color $--primary, font-size 13] /guides Guides
383383 @link [color $--gray, hover:color $--primary, font-size 13] /examples Examples
384384
385− @column [spacing 4]
385+ @el [spacing 4]
386386 @text [font-weight bold, font-size 12, color $--gray, text-transform uppercase, margin-bottom 4] Company
387387 @link [color $--gray, hover:color $--primary, font-size 13] /about About
388388 @link [color $--gray, hover:color $--primary, font-size 13] /blog Blog
389389 @link [color $--gray, hover:color $--primary, font-size 13] /careers Careers
390390 @link [color $--gray, hover:color $--primary, font-size 13] /contact Contact
391391
392− @column [spacing 4]
392+ @el [spacing 4]
393393 @text [font-weight bold, font-size 12, color $--gray, text-transform uppercase, margin-bottom 4] Legal
394394 @link [color $--gray, hover:color $--primary, font-size 13] /privacy Privacy Policy
395395 @link [color $--gray, hover:color $--primary, font-size 13] /terms Terms of Service
tests/snapshots/stress_large.html+1−1
@@ -1 +1 @@
1−<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Stress Test Large Document</title><style>@layer hl-reset,htmlang;@layer hl-reset{*,*::before,*::after{box-sizing:border-box}body{margin:0;font-family:system-ui,-apple-system,sans-serif}img{display:block}a{text-decoration:none;color:inherit}a:focus-visible,button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible{outline:2px solid currentColor;outline-offset:2px}}:root{--primary:#3b82f6;--secondary:#10b981;--accent:#f59e0b;--danger:#ef4444;--dark:#1e293b;--light:#f8fafc;--gray:#64748b;--border:#e2e8f0;--radius:8;--gap:16;--gap-sm:8;--gap-lg:24;}@layer htmlang{.a{display:flex;flex-direction:row;gap:0;min-height:100vh;}.b{display:flex;flex-direction:column;width:260px;background:white;border-right:1px solid var(--border);padding:16px;gap:8px;}.c{display:flex;flex-direction:row;gap:12px;padding:8px;align-items:center;}.d{flex-direction:column;width:36px;height:36px;border-radius:50%;background:var(--primary);color:white;display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:bold;}.e{display:flex;flex-direction:column;gap:2px;}.f{font-weight:bold;font-size:16px;color:var(--dark);}.g{font-size:12px;color:var(--gray);}.h{display:flex;flex-direction:column;width:100%;height:1px;background:var(--border);margin:8px 0;}.i{display:flex;flex-direction:column;margin-bottom:24px;}.j{font-weight:bold;font-size:12px;color:var(--gray);text-transform:uppercase;letter-spacing:1px;margin-bottom:8px;}.k{color:var(--primary);font-weight:bold;padding:8px 12px;background:#eff6ff;border-radius:6px;}.l{color:var(--gray);padding:8px 12px;border-radius:6px;transition:all 0.15s;}.m{display:flex;flex-direction:column;gap:4px;}.n{display:flex;flex-direction:row;gap:8px;align-items:center;}.o{display:flex;flex-direction:column;width:6px;height:6px;border-radius:50%;background:var(--secondary);}.p{font-size:13px;color:var(--gray);}.q{display:flex;flex-direction:column;width:6px;height:6px;border-radius:50%;background:var(--accent);}.r{display:flex;flex-direction:column;width:6px;height:6px;border-radius:50%;background:#cbd5e1;}.s{display:flex;flex-direction:column;margin-top:auto;padding:12px;background:#f1f5f9;border-radius:8px;}.t{flex-direction:column;width:28px;height:28px;border-radius:50%;background:var(--primary);color:white;display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:bold;}.u{display:flex;flex-direction:column;gap:0;}.v{font-size:13px;font-weight:bold;color:var(--dark);}.w{font-size:11px;color:var(--gray);}.x{display:flex;flex-direction:column;flex:1;min-width:0;background:var(--light);}.y{display:flex;flex-direction:column;padding:12px 24px;background:white;border-bottom:1px solid var(--border);}.z{display:flex;flex-direction:row;gap:16px;align-items:center;}.aa{display:flex;flex-direction:row;gap:8px;}.ab{color:var(--gray);font-size:14px;}.ac{color:var(--border);font-size:14px;}.ad{color:var(--dark);font-size:14px;}.ae{font-weight:bold;font-size:22px;color:var(--dark);}.af{display:flex;flex-direction:column;flex:1;min-width:0;}.ag{display:flex;flex-direction:row;gap:12px;align-items:center;}.ah{padding:8px 12px;border-radius:6px;border:1px solid var(--border);width:240px;transition:all 0.2s;}.ai{display:flex;flex-direction:column;position:relative;}.aj{padding:8px 16px;background:var(--primary);color:white;border-radius:6px;border:none;cursor:pointer;transition:all 0.2s;font-size:14px;}.ak{display:flex;flex-direction:column;position:absolute;top:-2px;right:-2px;}.al{display:flex;flex-direction:column;width:8px;height:8px;border-radius:50%;background:var(--danger);}.am{padding:8px 16px;background:var(--gray);color:white;border-radius:6px;border:none;cursor:pointer;transition:all 0.2s;font-size:14px;}.an{display:flex;flex-direction:column;padding:24px;overflow-y:auto;}.ao{display:flex;flex-direction:column;background:#eff6ff;border:1px solid #bfdbfe;border-radius:8px;padding:12px 16px;}.ap{color:#1e40af;font-size:14px;}.aq,.av{display:flex;flex-direction:row;gap:16px;margin-top:24px;}.ar{display:flex;flex-direction:column;background:white;border-radius:8px;padding:16px;border:1px solid var(--border);}.as{font-size:14px;color:var(--gray);}.at{font-weight:bold;font-size:28px;color:var(--dark);margin-top:4px;}.au{font-size:12px;color:var(--secondary);margin-top:2px;}.aw{display:flex;flex-direction:column;background:white;border-radius:8px;padding:16px;border:1px solid var(--border);transition:all 0.2s;animation:fade-in 0.3s ease;}.ax{font-weight:bold;font-size:18px;color:var(--dark);}.ay{display:flex;flex-direction:column;margin-top:8px;}.az{flex-direction:column;height:200px;background:var(--light);border-radius:6px;margin-top:12px;display:flex;align-items:flex-end;padding:16px;gap:8px;}.a0{display:flex;flex-direction:column;width:100%;height:40%;background:var(--primary);border-radius:4px 4px 0 0;transition:all 0.2s;min-width:20px;}.a1{display:flex;flex-direction:column;width:100%;height:65%;background:var(--primary);border-radius:4px 4px 0 0;transition:all 0.2s;min-width:20px;}.a2{display:flex;flex-direction:column;width:100%;height:45%;background:var(--primary);border-radius:4px 4px 0 0;transition:all 0.2s;min-width:20px;}.a3{display:flex;flex-direction:column;width:100%;height:80%;background:var(--primary);border-radius:4px 4px 0 0;transition:all 0.2s;min-width:20px;}.a4{display:flex;flex-direction:column;width:100%;height:55%;background:var(--primary);border-radius:4px 4px 0 0;transition:all 0.2s;min-width:20px;}.a5{display:flex;flex-direction:column;width:100%;height:70%;background:var(--primary);border-radius:4px 4px 0 0;transition:all 0.2s;min-width:20px;}.a6{display:flex;flex-direction:column;width:100%;height:90%;background:var(--primary);border-radius:4px 4px 0 0;transition:all 0.2s;min-width:20px;}.a7{display:flex;flex-direction:column;width:100%;height:60%;background:var(--primary);border-radius:4px 4px 0 0;transition:all 0.2s;min-width:20px;}.a8{display:flex;flex-direction:column;width:100%;height:75%;background:var(--primary);border-radius:4px 4px 0 0;transition:all 0.2s;min-width:20px;}.a9{display:flex;flex-direction:column;width:100%;height:85%;background:var(--primary);border-radius:4px 4px 0 0;transition:all 0.2s;min-width:20px;}.ba{display:flex;flex-direction:column;width:100%;height:50%;background:var(--primary);border-radius:4px 4px 0 0;transition:all 0.2s;min-width:20px;}.bb{display:flex;flex-direction:column;width:100%;height:95%;background:var(--primary);border-radius:4px 4px 0 0;transition:all 0.2s;min-width:20px;}.bc{display:flex;flex-direction:column;gap:12px;margin-top:12px;}.bd{display:flex;flex-direction:row;gap:12px;align-items:center;padding:8px;border-radius:6px;}.be{flex-direction:column;width:32px;height:32px;border-radius:50%;background:var(--primary);color:white;display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:bold;}.bf{display:flex;flex-direction:column;gap:2px;flex:1;min-width:0;}.bg{font-size:14px;font-weight:bold;color:var(--dark);}.bh{display:flex;flex-direction:column;flex:1;min-width:0;gap:16px;}.bi{display:flex;flex-direction:column;gap:0;margin-top:12px;}.bj{display:flex;flex-direction:row;gap:0;padding:8px 16px;background:var(--light);border-bottom:1px solid var(--border);}.bk{display:flex;flex-direction:column;width:200px;}.bl{font-weight:bold;font-size:12px;color:var(--gray);text-transform:uppercase;}.bm{display:flex;flex-direction:column;width:150px;}.bn{display:flex;flex-direction:column;width:120px;}.bo{display:flex;flex-direction:row;gap:0;padding:12px 16px;border-bottom:1px solid var(--border);}.bp{font-size:14px;}.bq{display:flex;flex-direction:row;gap:0;}.br{font-size:13px;color:var(--dark);flex:1;min-width:0;}.bs{display:flex;flex-direction:column;width:100%;height:8px;background:var(--border);border-radius:4px;overflow:hidden;}.bt{display:flex;flex-direction:column;width:67%;height:100%;background:var(--primary);border-radius:4px;}.bu{display:flex;flex-direction:column;gap:8px;margin-top:12px;}.bv{display:flex;flex-direction:row;gap:12px;padding:8px 12px;align-items:center;}.bw{flex-direction:column;width:24px;height:24px;border-radius:50%;background:#eff6ff;display:flex;align-items:center;justify-content:center;}.bx{font-size:10px;color:var(--primary);font-weight:bold;}.by{font-size:14px;color:var(--dark);flex:1;min-width:0;}.bz{display:flex;flex-direction:column;width:340px;gap:16px;}.b0{padding:8px 16px;background:var(--secondary);color:white;border-radius:6px;border:none;cursor:pointer;transition:all 0.2s;font-size:14px;}.b1{padding:8px 16px;background:var(--accent);color:white;border-radius:6px;border:none;cursor:pointer;transition:all 0.2s;font-size:14px;}.b2{padding:8px 16px;background:var(--gray);color:white;border-radius:6px;border:none;cursor:pointer;transition:all 0.2s;font-size:14px;}.b3{display:flex;flex-direction:row;gap:10px;align-items:center;padding:6px 8px;border-radius:6px;transition:all 0.15s;}.b4{display:flex;flex-direction:column;gap:0;flex:1;min-width:0;}.b5{display:flex;flex-direction:column;width:8px;height:8px;border-radius:50%;background:var(--secondary);}.b6{display:flex;flex-direction:row;gap:0;flex-wrap:wrap;margin-top:8px;}.b7{flex-direction:column;display:inline-block;padding:4px 10px;background:#f1f5f9;color:var(--gray);border-radius:4px;font-size:12px;margin:2px;}.b8{display:flex;flex-direction:row;gap:10px;padding:10px 12px;border-bottom:1px solid var(--border);align-items:center;}.b9{display:flex;flex-direction:row;gap:0;align-items:center;}.ca{display:flex;flex-direction:column;width:40px;height:22px;border-radius:11px;background:var(--primary);padding:2px;cursor:pointer;transition:all 0.2s;}.cb{display:flex;flex-direction:column;width:18px;height:18px;border-radius:50%;background:white;margin-left:18px;transition:all 0.2s;}.cc{display:flex;flex-direction:column;width:40px;height:22px;border-radius:11px;background:#cbd5e1;padding:2px;cursor:pointer;transition:all 0.2s;}.cd{display:flex;flex-direction:column;width:18px;height:18px;border-radius:50%;background:white;transition:all 0.2s;}.ce{display:flex;flex-direction:column;margin-top:24px;}.cf{display:flex;flex-direction:row;gap:16px;margin-bottom:12px;align-items:center;}.cg{padding:8px 12px;border-radius:6px;border:1px solid var(--border);width:240px;}.ch{padding:6px 12px;border-radius:4px;border:1px solid var(--border);background:white;color:var(--gray);font-size:13px;cursor:pointer;transition:all 0.15s;}.ci{display:flex;flex-direction:row;gap:0;padding:8px 16px;background:var(--light);border-bottom:2px solid var(--border);border-radius:6px 6px 0 0;}.cj{display:flex;flex-direction:column;width:60px;}.ck{display:flex;flex-direction:row;gap:0;padding:10px 16px;border-bottom:1px solid var(--border);cursor:pointer;transition:all 0.1s;}.cl{flex-direction:column;width:24px;height:24px;border-radius:50%;background:var(--primary);color:white;display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:bold;}.cm{font-size:14px;color:var(--dark);}.cn{flex-direction:column;display:inline-block;padding:2px 8px;background:var(--secondary);color:white;border-radius:12px;font-size:12px;}.co{display:flex;flex-direction:row;gap:16px;padding:12px 16px;align-items:center;border-top:1px solid var(--border);}.cp{display:flex;flex-direction:row;gap:4px;}.cq{padding:6px 10px;border-radius:4px;border:1px solid var(--border);background:white;color:var(--gray);font-size:13px;cursor:pointer;}.cr{padding:6px 10px;border-radius:4px;border:1px solid var(--primary);background:var(--primary);color:white;font-size:13px;cursor:pointer;}.cs{display:flex;flex-direction:column;padding:24px 24px;background:white;border-top:1px solid var(--border);}.ct{display:flex;flex-direction:row;gap:24px;}.cu{display:flex;flex-direction:column;gap:8px;flex:1;min-width:0;}.cv{font-weight:bold;font-size:14px;color:var(--dark);}.cw{font-weight:bold;font-size:12px;color:var(--gray);text-transform:uppercase;margin-bottom:4px;}.cx{color:var(--gray);font-size:13px;}.l:hover{color:var(--primary);background:#f1f5f9;}.ab:hover,.cx:hover{color:var(--primary);}.aj:hover,.am:hover,.b0:hover,.b1:hover,.b2:hover{background:var(--dark);}.aw:hover{box-shadow:0 4 12 rgba(0,0,0,0.1);}.a0:hover,.a1:hover,.a2:hover,.a3:hover,.a4:hover,.a5:hover,.a6:hover,.a7:hover,.a8:hover,.a9:hover,.ba:hover,.bb:hover{background:#2563eb;}.bd:hover,.bo:hover,.ck:hover{background:var(--light);}.b3:hover{background:#f1f5f9;}.ch:hover{background:#f1f5f9;color:var(--dark);}.ah:focus{border:1px solid var(--primary);}@media(min-width:640px){.aq,.ct{flex-direction:column;}.bz{flex:1;min-width:0;}}@media(min-width:1024px){.aq,.ct{flex-direction:row;}}@media(prefers-color-scheme:dark){.b{background:#0f172a;border-right:1px solid var(--dark);}.f,.v,.ad,.ae,.at,.ax,.bg,.br,.by,.cm,.cv{color:white;}.h,.bs{background:#334155;}.k,.bw{background:#1e3a5f;}.s,.ch,.cq{background:var(--dark);}.x,.az,.bj,.ci{background:#0f172a;}.y{background:#0f172a;border-bottom:1px solid var(--dark);}.ah{border:1px solid #334155;background:var(--dark);color:white;}.ar,.aw{background:var(--dark);border:1px solid #334155;}.bo,.b8,.ck{border-bottom:1px solid #334155;}.b7{background:#334155;color:#94a3b8;}.cc{background:#475569;}.cs{background:#0f172a;border-top:1px solid var(--dark);}}}@keyframes fade-in {from{opacity:0}to{opacity:1}}@keyframes slide-down {0%{transform:translateY(-10px);opacity:0}100%{transform:translateY(0);opacity:1}}</style></head><body><div class="a"><div class="b"><div class="c"><div class="d"><span>HL</span></div><div class="e"><span class="f">htmlang</span><span class="g">Dashboard v2.0</span></div></div><div class="h"></div><div class="i"><span class="j">Navigation</span><div class="e"><a href="/dashboard" class="k">Dashboard</a><a href="/analytics" class="l">Analytics</a><a href="/projects" class="l">Projects</a><a href="/team" class="l">Team</a><a href="/messages" class="l">Messages</a><a href="/calendar" class="l">Calendar</a><a href="/documents" class="l">Documents</a><a href="/settings" class="l">Settings</a></div></div><div class="i"><span class="j">Favorites</span><div class="e"><a href="/project/alpha" class="l">Project Alpha</a><a href="/project/beta" class="l">Project Beta</a><a href="/reports/q4" class="l">Q4 Reports</a></div></div><div class="i"><span class="j">Shortcuts</span><div class="m"><div class="n"><div class="o"></div><span class="p">Online (12)</span></div><div class="n"><div class="q"></div><span class="p">Away (3)</span></div><div class="n"><div class="r"></div><span class="p">Offline (5)</span></div></div></div><div class="s"><div class="n"><div class="t"><span>JD</span></div><div class="u"><span class="v">Jane Doe</span><span class="w">jane@example.com</span></div></div></div></div><div class="x"><header class="y"><div class="z"><div class="e"><div class="aa"><div class="aa"><a href="/" class="ab">Home</a><span class="ac">/</span></div><span class="ad">Dashboard</span></div><span class="ae">Dashboard Overview</span></div><div class="af"></div><div class="ag"><input class="ah" type="search" placeholder="Search..."><div class="ai"><button class="aj">Alerts</button><div class="ak"><div class="al"></div></div></div><button class="am">Settings</button></div></div></header><div class="an"><div class="ao"><span class="ap">Welcome back! You have 3 new notifications and 2 pending tasks.</span></div><div class="aq"><div class="ar"><span class="as">Total Revenue</span><span class="at">$48</span><span class="au">+12.5% from last month</span></div><div class="ar"><span class="as">Active Users</span><span class="at">2</span><span class="au">+8.2% from last week</span></div><div class="ar"><span class="as">Conversion Rate</span><span class="at">3.24%</span><span class="au">+0.4% from yesterday</span></div><div class="ar"><span class="as">Open Tickets</span><span class="at">142</span><span class="au">-5.1% from last month</span></div></div><div class="av"><div class="aw"><span class="ax">Revenue Overview</span><div class="ay"><div class="az"><div class="a0"></div><div class="a1"></div><div class="a2"></div><div class="a3"></div><div class="a4"></div><div class="a5"></div><div class="a6"></div><div class="a7"></div><div class="a8"></div><div class="a9"></div><div class="ba"></div><div class="bb"></div></div></div></div><div class="aw"><span class="ax">Activity Feed</span><div class="ay"><div class="bc"><div class="bd"><div class="be"><span>Alice</span></div><div class="bf"><span class="bg">Alice</span><span class="g">Updated project files</span></div><span class="w">2h ago</span></div><div class="bd"><div class="be"><span>Bob</span></div><div class="bf"><span class="bg">Bob</span><span class="g">Updated project files</span></div><span class="w">2h ago</span></div><div class="bd"><div class="be"><span>Carol</span></div><div class="bf"><span class="bg">Carol</span><span class="g">Updated project files</span></div><span class="w">2h ago</span></div><div class="bd"><div class="be"><span>Dave</span></div><div class="bf"><span class="bg">Dave</span><span class="g">Updated project files</span></div><span class="w">2h ago</span></div><div class="bd"><div class="be"><span>Eve</span></div><div class="bf"><span class="bg">Eve</span><span class="g">Updated project files</span></div><span class="w">2h ago</span></div><div class="bd"><div class="be"><span>Frank</span></div><div class="bf"><span class="bg">Frank</span><span class="g">Updated project files</span></div><span class="w">2h ago</span></div><div class="bd"><div class="be"><span>Grace</span></div><div class="bf"><span class="bg">Grace</span><span class="g">Updated project files</span></div><span class="w">2h ago</span></div><div class="bd"><div class="be"><span>Hank</span></div><div class="bf"><span class="bg">Hank</span><span class="g">Updated project files</span></div><span class="w">2h ago</span></div></div></div></div></div><div class="aq"><div class="bh"><div class="aw"><span class="ax">Project Status</span><div class="ay"><div class="bi"><div class="bj"><div class="bk"><span class="bl">Project</span></div><div class="bm"><span class="bl">Status</span></div><div class="bn"><span class="bl">Progress</span></div><div class="af"><span class="bl">Due Date</span></div></div><div class="bo"><div class="bk"><span class="bp">Project Alpha</span></div><div class="bm"><span class="as">In Progress</span></div><div class="bn"><span class="bp">75%</span></div><div class="af"><span class="as">Dec 15 2025</span></div></div><div class="bo"><div class="bk"><span class="bp">Project Beta</span></div><div class="bm"><span class="as">Review</span></div><div class="bn"><span class="bp">90%</span></div><div class="af"><span class="as">Nov 30 2025</span></div></div><div class="bo"><div class="bk"><span class="bp">Project Gamma</span></div><div class="bm"><span class="as">Planning</span></div><div class="bn"><span class="bp">20%</span></div><div class="af"><span class="as">Jan 20 2026</span></div></div><div class="bo"><div class="bk"><span class="bp">Project Delta</span></div><div class="bm"><span class="as">Completed</span></div><div class="bn"><span class="bp">100%</span></div><div class="af"><span class="as">Oct 10 2025</span></div></div><div class="bo"><div class="bk"><span class="bp">Project Epsilon</span></div><div class="bm"><span class="as">On Hold</span></div><div class="bn"><span class="bp">45%</span></div><div class="af"><span class="as">Feb 28 2026</span></div></div></div></div></div><div class="aw"><span class="ax">Progress Breakdown</span><div class="ay"><div class="bc"><div class="m"><div class="bq"><span class="br">Alpha</span><span class="p">67%</span></div><div class="bs"><div class="bt"></div></div></div><div class="m"><div class="bq"><span class="br">Beta</span><span class="p">67%</span></div><div class="bs"><div class="bt"></div></div></div><div class="m"><div class="bq"><span class="br">Gamma</span><span class="p">67%</span></div><div class="bs"><div class="bt"></div></div></div><div class="m"><div class="bq"><span class="br">Delta</span><span class="p">67%</span></div><div class="bs"><div class="bt"></div></div></div><div class="m"><div class="bq"><span class="br">Epsilon</span><span class="p">67%</span></div><div class="bs"><div class="bt"></div></div></div></div></div></div><div class="aw"><span class="ax">Recent Activity Log</span><div class="ay"><div class="bu"><div class="bv"><div class="bw"><span class="bx">0</span></div><span class="by">Deployed v2.3.1 to production</span><span class="w">just now</span></div><div class="bv"><div class="bw"><span class="bx">1</span></div><span class="by">Merged feature/auth-redesign</span><span class="w">just now</span></div><div class="bv"><div class="bw"><span class="bx">2</span></div><span class="by">Closed issue #482: Login timeout</span><span class="w">just now</span></div><div class="bv"><div class="bw"><span class="bx">3</span></div><span class="by">Updated CI/CD pipeline config</span><span class="w">just now</span></div><div class="bv"><div class="bw"><span class="bx">4</span></div><span class="by">Added unit tests for payment module</span><span class="w">just now</span></div><div class="bv"><div class="bw"><span class="bx">5</span></div><span class="by">Reviewed PR #156: API refactor</span><span class="w">just now</span></div><div class="bv"><div class="bw"><span class="bx">6</span></div><span class="by">Fixed memory leak in worker pool</span><span class="w">just now</span></div><div class="bv"><div class="bw"><span class="bx">7</span></div><span class="by">Released hotfix 2.3.2</span><span class="w">just now</span></div></div></div></div></div><div class="bz"><div class="aw"><span class="ax">Quick Actions</span><div class="ay"><div class="bu"><button class="aj">New Project</button><button class="b0">Create Report</button><button class="b1">Invite Member</button><button class="b2">View Backlog</button></div></div></div><div class="aw"><span class="ax">Team Members</span><div class="ay"><div class="bu"><div class="b3"><div class="t"><span>Alice</span></div><div class="b4"><span class="v">Alice</span><span class="w">Developer</span></div><div class="b5"></div></div><div class="b3"><div class="t"><span>Bob</span></div><div class="b4"><span class="v">Bob</span><span class="w">Developer</span></div><div class="b5"></div></div><div class="b3"><div class="t"><span>Carol</span></div><div class="b4"><span class="v">Carol</span><span class="w">Developer</span></div><div class="b5"></div></div><div class="b3"><div class="t"><span>Dave</span></div><div class="b4"><span class="v">Dave</span><span class="w">Developer</span></div><div class="b5"></div></div><div class="b3"><div class="t"><span>Eve</span></div><div class="b4"><span class="v">Eve</span><span class="w">Developer</span></div><div class="b5"></div></div><div class="b3"><div class="t"><span>Frank</span></div><div class="b4"><span class="v">Frank</span><span class="w">Developer</span></div><div class="b5"></div></div><div class="b3"><div class="t"><span>Grace</span></div><div class="b4"><span class="v">Grace</span><span class="w">Developer</span></div><div class="b5"></div></div><div class="b3"><div class="t"><span>Hank</span></div><div class="b4"><span class="v">Hank</span><span class="w">Developer</span></div><div class="b5"></div></div></div></div></div><div class="aw"><span class="ax">Tags</span><div class="ay"><div class="b6"><div class="b7"><span>frontend</span></div><div class="b7"><span>backend</span></div><div class="b7"><span>devops</span></div><div class="b7"><span>design</span></div><div class="b7"><span>mobile</span></div><div class="b7"><span>security</span></div><div class="b7"><span>performance</span></div><div class="b7"><span>testing</span></div><div class="b7"><span>docs</span></div><div class="b7"><span>infra</span></div><div class="b7"><span>ux</span></div><div class="b7"><span>api</span></div></div></div></div><div class="aw"><span class="ax">Notifications</span><div class="ay"><div class="bi"><div class="b8"><div class="al"></div><span class="br">New deployment completed</span><span class="w">now</span></div><div class="b8"><div class="al"></div><span class="br">PR review requested</span><span class="w">now</span></div><div class="b8"><div class="al"></div><span class="br">Build failed on staging</span><span class="w">now</span></div><div class="b8"><div class="al"></div><span class="br">Meeting in 30 minutes</span><span class="w">now</span></div><div class="b8"><div class="al"></div><span class="br">Subscription renewal due</span><span class="w">now</span></div></div></div></div><div class="aw"><span class="ax">Settings</span><div class="ay"><div class="bc"><div class="b9"><span class="by">Dark Mode</span><div class="ca"><div class="cb"></div></div></div><div class="b9"><span class="by">Notifications</span><div class="ca"><div class="cb"></div></div></div><div class="b9"><span class="by">Auto-save</span><div class="cc"><div class="cd"></div></div></div><div class="b9"><span class="by">Compact View</span><div class="cc"><div class="cd"></div></div></div></div></div></div></div></div><div class="ce"><div class="aw"><span class="ax">Data Table</span><div class="ay"><div class="bi"><div class="cf"><input class="cg" type="search" placeholder="Filter results..."><div class="af"></div><div class="aa"><button class="ch">all</button><button class="ch">design</button><button class="ch">development</button><button class="ch">marketing</button><button class="ch">analytics</button></div></div><div class="ci"><div class="cj"><span class="bl">ID</span></div><div class="bk"><span class="bl">Name</span></div><div class="bm"><span class="bl">Category</span></div><div class="bn"><span class="bl">Status</span></div><div class="af"><span class="bl">Updated</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Alpha</span></div><span class="cm">Alpha</span></div></div><div class="bm"><span class="p">active</span></div><div class="bn"><div class="cn"><span>active</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Beta</span></div><span class="cm">Beta</span></div></div><div class="bm"><span class="p">active</span></div><div class="bn"><div class="cn"><span>active</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Gamma</span></div><span class="cm">Gamma</span></div></div><div class="bm"><span class="p">active</span></div><div class="bn"><div class="cn"><span>active</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Delta</span></div><span class="cm">Delta</span></div></div><div class="bm"><span class="p">active</span></div><div class="bn"><div class="cn"><span>active</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Epsilon</span></div><span class="cm">Epsilon</span></div></div><div class="bm"><span class="p">active</span></div><div class="bn"><div class="cn"><span>active</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Alpha</span></div><span class="cm">Alpha</span></div></div><div class="bm"><span class="p">pending</span></div><div class="bn"><div class="cn"><span>pending</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Beta</span></div><span class="cm">Beta</span></div></div><div class="bm"><span class="p">pending</span></div><div class="bn"><div class="cn"><span>pending</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Gamma</span></div><span class="cm">Gamma</span></div></div><div class="bm"><span class="p">pending</span></div><div class="bn"><div class="cn"><span>pending</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Delta</span></div><span class="cm">Delta</span></div></div><div class="bm"><span class="p">pending</span></div><div class="bn"><div class="cn"><span>pending</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Epsilon</span></div><span class="cm">Epsilon</span></div></div><div class="bm"><span class="p">pending</span></div><div class="bn"><div class="cn"><span>pending</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Alpha</span></div><span class="cm">Alpha</span></div></div><div class="bm"><span class="p">completed</span></div><div class="bn"><div class="cn"><span>completed</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Beta</span></div><span class="cm">Beta</span></div></div><div class="bm"><span class="p">completed</span></div><div class="bn"><div class="cn"><span>completed</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Gamma</span></div><span class="cm">Gamma</span></div></div><div class="bm"><span class="p">completed</span></div><div class="bn"><div class="cn"><span>completed</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Delta</span></div><span class="cm">Delta</span></div></div><div class="bm"><span class="p">completed</span></div><div class="bn"><div class="cn"><span>completed</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Epsilon</span></div><span class="cm">Epsilon</span></div></div><div class="bm"><span class="p">completed</span></div><div class="bn"><div class="cn"><span>completed</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Alpha</span></div><span class="cm">Alpha</span></div></div><div class="bm"><span class="p">archived</span></div><div class="bn"><div class="cn"><span>archived</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Beta</span></div><span class="cm">Beta</span></div></div><div class="bm"><span class="p">archived</span></div><div class="bn"><div class="cn"><span>archived</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Gamma</span></div><span class="cm">Gamma</span></div></div><div class="bm"><span class="p">archived</span></div><div class="bn"><div class="cn"><span>archived</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Delta</span></div><span class="cm">Delta</span></div></div><div class="bm"><span class="p">archived</span></div><div class="bn"><div class="cn"><span>archived</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Epsilon</span></div><span class="cm">Epsilon</span></div></div><div class="bm"><span class="p">archived</span></div><div class="bn"><div class="cn"><span>archived</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="co"><span class="p">Showing 1-20 of 142 results</span><div class="af"></div><div class="cp"><button class="cq">Prev</button><button class="cr">1</button><button class="cq">2</button><button class="cq">3</button><button class="cq">Next</button></div></div></div></div></div></div></div><footer class="cs"><div class="ct"><div class="cu"><span class="cv">htmlang Dashboard</span><span class="g">Built with htmlang - a declarative HTML language</span><span class="w">Copyright 2025 htmlang contributors</span></div><div class="m"><span class="cw">Product</span><a href="/features" class="cx">Features</a><a href="/pricing" class="cx">Pricing</a><a href="/changelog" class="cx">Changelog</a><a href="/roadmap" class="cx">Roadmap</a></div><div class="m"><span class="cw">Resources</span><a href="/docs" class="cx">Documentation</a><a href="/api" class="cx">API Reference</a><a href="/guides" class="cx">Guides</a><a href="/examples" class="cx">Examples</a></div><div class="m"><span class="cw">Company</span><a href="/about" class="cx">About</a><a href="/blog" class="cx">Blog</a><a href="/careers" class="cx">Careers</a><a href="/contact" class="cx">Contact</a></div><div class="m"><span class="cw">Legal</span><a href="/privacy" class="cx">Privacy Policy</a><a href="/terms" class="cx">Terms of Service</a><a href="/cookies" class="cx">Cookie Policy</a></div></div></footer></div></div></body></html>
1+<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Stress Test Large Document</title><style>@layer hl-reset,htmlang;@layer hl-reset{*,*::before,*::after{box-sizing:border-box}body{margin:0;font-family:system-ui,-apple-system,sans-serif}img{display:block}a{text-decoration:none;color:inherit}a:focus-visible,button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible{outline:2px solid currentColor;outline-offset:2px}}:root{--primary:#3b82f6;--secondary:#10b981;--accent:#f59e0b;--danger:#ef4444;--dark:#1e293b;--light:#f8fafc;--gray:#64748b;--border:#e2e8f0;--radius:8;--gap:16;--gap-sm:8;--gap-lg:24;}@layer htmlang{.a{display:flex;flex-direction:row;gap:0;min-height:100vh;}.b{display:flex;flex-direction:column;width:260px;background:white;border-right:1px solid var(--border);padding:16px;gap:8px;}.c{display:flex;flex-direction:row;gap:12px;padding:8px;align-items:center;}.d{flex-direction:column;width:36px;height:36px;border-radius:50%;background:var(--primary);color:white;display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:bold;}.e{display:flex;flex-direction:column;gap:2px;}.f{font-weight:bold;font-size:16px;color:var(--dark);}.g{font-size:12px;color:var(--gray);}.h{display:flex;flex-direction:column;width:100%;height:1px;background:var(--border);margin:8px 0;}.i{display:flex;flex-direction:column;margin-bottom:24px;}.j{font-weight:bold;font-size:12px;color:var(--gray);text-transform:uppercase;letter-spacing:1px;margin-bottom:8px;}.k{color:var(--primary);font-weight:bold;padding:8px 12px;background:#eff6ff;border-radius:6px;}.l{color:var(--gray);padding:8px 12px;border-radius:6px;transition:all 0.15s;}.m{display:flex;flex-direction:column;gap:4px;}.n{display:flex;flex-direction:row;gap:8px;align-items:center;}.o{display:flex;flex-direction:column;width:6px;height:6px;border-radius:50%;background:var(--secondary);}.p{font-size:13px;color:var(--gray);}.q{display:flex;flex-direction:column;width:6px;height:6px;border-radius:50%;background:var(--accent);}.r{display:flex;flex-direction:column;width:6px;height:6px;border-radius:50%;background:#cbd5e1;}.s{display:flex;flex-direction:column;margin-top:auto;padding:12px;background:#f1f5f9;border-radius:8px;}.t{flex-direction:column;width:28px;height:28px;border-radius:50%;background:var(--primary);color:white;display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:bold;}.u{display:flex;flex-direction:column;gap:0;}.v{font-size:13px;font-weight:bold;color:var(--dark);}.w{font-size:11px;color:var(--gray);}.x{display:flex;flex-direction:column;flex:1;min-width:0;background:var(--light);}.y{display:flex;flex-direction:column;padding:12px 24px;background:white;border-bottom:1px solid var(--border);}.z{display:flex;flex-direction:row;gap:16px;align-items:center;}.aa{display:flex;flex-direction:row;gap:8px;}.ab{color:var(--gray);font-size:14px;}.ac{color:var(--border);font-size:14px;}.ad{color:var(--dark);font-size:14px;}.ae{font-weight:bold;font-size:22px;color:var(--dark);}.af{display:flex;flex-direction:column;flex:1;min-width:0;}.ag{display:flex;flex-direction:row;gap:12px;align-items:center;}.ah{padding:8px 12px;border-radius:6px;border:1px solid var(--border);width:240px;transition:all 0.2s;}.ai{display:flex;flex-direction:column;position:relative;}.aj{padding:8px 16px;background:var(--primary);color:white;border-radius:6px;border:none;cursor:pointer;transition:all 0.2s;font-size:14px;}.ak{display:flex;flex-direction:column;position:absolute;top:-2px;right:-2px;}.al{display:flex;flex-direction:column;width:8px;height:8px;border-radius:50%;background:var(--danger);}.am{padding:8px 16px;background:var(--gray);color:white;border-radius:6px;border:none;cursor:pointer;transition:all 0.2s;font-size:14px;}.an{display:flex;flex-direction:column;padding:24px;overflow-y:auto;}.ao{display:flex;flex-direction:column;background:#eff6ff;border:1px solid #bfdbfe;border-radius:8px;padding:12px 16px;}.ap{color:#1e40af;font-size:14px;}.aq,.av{display:flex;flex-direction:row;gap:16px;margin-top:24px;}.ar{display:flex;flex-direction:column;background:white;border-radius:8px;padding:16px;border:1px solid var(--border);}.as{font-size:14px;color:var(--gray);}.at{font-weight:bold;font-size:28px;color:var(--dark);margin-top:4px;}.au{font-size:12px;color:var(--secondary);margin-top:2px;}.aw{display:flex;flex-direction:column;background:white;border-radius:8px;padding:16px;border:1px solid var(--border);transition:all 0.2s;animation:fade-in 0.3s ease;}.ax{font-weight:bold;font-size:18px;color:var(--dark);}.ay{display:flex;flex-direction:column;margin-top:8px;}.az{flex-direction:column;height:200px;background:var(--light);border-radius:6px;margin-top:12px;display:flex;align-items:flex-end;padding:16px;gap:8px;}.a0{display:flex;flex-direction:column;width:100%;height:40%;background:var(--primary);border-radius:4px 4px 0 0;transition:all 0.2s;min-width:20px;}.a1{display:flex;flex-direction:column;width:100%;height:65%;background:var(--primary);border-radius:4px 4px 0 0;transition:all 0.2s;min-width:20px;}.a2{display:flex;flex-direction:column;width:100%;height:45%;background:var(--primary);border-radius:4px 4px 0 0;transition:all 0.2s;min-width:20px;}.a3{display:flex;flex-direction:column;width:100%;height:80%;background:var(--primary);border-radius:4px 4px 0 0;transition:all 0.2s;min-width:20px;}.a4{display:flex;flex-direction:column;width:100%;height:55%;background:var(--primary);border-radius:4px 4px 0 0;transition:all 0.2s;min-width:20px;}.a5{display:flex;flex-direction:column;width:100%;height:70%;background:var(--primary);border-radius:4px 4px 0 0;transition:all 0.2s;min-width:20px;}.a6{display:flex;flex-direction:column;width:100%;height:90%;background:var(--primary);border-radius:4px 4px 0 0;transition:all 0.2s;min-width:20px;}.a7{display:flex;flex-direction:column;width:100%;height:60%;background:var(--primary);border-radius:4px 4px 0 0;transition:all 0.2s;min-width:20px;}.a8{display:flex;flex-direction:column;width:100%;height:75%;background:var(--primary);border-radius:4px 4px 0 0;transition:all 0.2s;min-width:20px;}.a9{display:flex;flex-direction:column;width:100%;height:85%;background:var(--primary);border-radius:4px 4px 0 0;transition:all 0.2s;min-width:20px;}.ba{display:flex;flex-direction:column;width:100%;height:50%;background:var(--primary);border-radius:4px 4px 0 0;transition:all 0.2s;min-width:20px;}.bb{display:flex;flex-direction:column;width:100%;height:95%;background:var(--primary);border-radius:4px 4px 0 0;transition:all 0.2s;min-width:20px;}.bc{display:flex;flex-direction:column;gap:12px;margin-top:12px;}.bd{display:flex;flex-direction:row;gap:12px;align-items:center;padding:8px;border-radius:6px;}.be{flex-direction:column;width:32px;height:32px;border-radius:50%;background:var(--primary);color:white;display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:bold;}.bf{display:flex;flex-direction:column;gap:2px;flex:1;min-width:0;}.bg{font-size:14px;font-weight:bold;color:var(--dark);}.bh{display:flex;flex-direction:column;flex:1;min-width:0;gap:16px;}.bi{display:flex;flex-direction:column;gap:0;margin-top:12px;}.bj{display:flex;flex-direction:row;gap:0;padding:8px 16px;background:var(--light);border-bottom:1px solid var(--border);}.bk{display:flex;flex-direction:column;width:200px;}.bl{font-weight:bold;font-size:12px;color:var(--gray);text-transform:uppercase;}.bm{display:flex;flex-direction:column;width:150px;}.bn{display:flex;flex-direction:column;width:120px;}.bo{display:flex;flex-direction:row;gap:0;padding:12px 16px;border-bottom:1px solid var(--border);}.bp{font-size:14px;}.bq{display:flex;flex-direction:row;gap:0;}.br{font-size:13px;color:var(--dark);flex:1;min-width:0;}.bs{display:flex;flex-direction:column;width:100%;height:8px;background:var(--border);border-radius:4px;overflow:hidden;}.bt{display:flex;flex-direction:column;width:67%;flex:1;min-height:0;background:var(--primary);border-radius:4px;}.bu{display:flex;flex-direction:column;gap:8px;margin-top:12px;}.bv{display:flex;flex-direction:row;gap:12px;padding:8px 12px;align-items:center;}.bw{flex-direction:column;width:24px;height:24px;border-radius:50%;background:#eff6ff;display:flex;align-items:center;justify-content:center;}.bx{font-size:10px;color:var(--primary);font-weight:bold;}.by{font-size:14px;color:var(--dark);flex:1;min-width:0;}.bz{display:flex;flex-direction:column;width:340px;gap:16px;}.b0{padding:8px 16px;background:var(--secondary);color:white;border-radius:6px;border:none;cursor:pointer;transition:all 0.2s;font-size:14px;}.b1{padding:8px 16px;background:var(--accent);color:white;border-radius:6px;border:none;cursor:pointer;transition:all 0.2s;font-size:14px;}.b2{padding:8px 16px;background:var(--gray);color:white;border-radius:6px;border:none;cursor:pointer;transition:all 0.2s;font-size:14px;}.b3{display:flex;flex-direction:row;gap:10px;align-items:center;padding:6px 8px;border-radius:6px;transition:all 0.15s;}.b4{display:flex;flex-direction:column;gap:0;flex:1;min-width:0;}.b5{display:flex;flex-direction:column;width:8px;height:8px;border-radius:50%;background:var(--secondary);}.b6{display:flex;flex-direction:row;gap:0;flex-wrap:wrap;margin-top:8px;}.b7{flex-direction:column;display:inline-block;padding:4px 10px;background:#f1f5f9;color:var(--gray);border-radius:4px;font-size:12px;margin:2px;}.b8{display:flex;flex-direction:row;gap:10px;padding:10px 12px;border-bottom:1px solid var(--border);align-items:center;}.b9{display:flex;flex-direction:row;gap:0;align-items:center;}.ca{display:flex;flex-direction:column;width:40px;height:22px;border-radius:11px;background:var(--primary);padding:2px;cursor:pointer;transition:all 0.2s;}.cb{display:flex;flex-direction:column;width:18px;height:18px;border-radius:50%;background:white;margin-left:18px;transition:all 0.2s;}.cc{display:flex;flex-direction:column;width:40px;height:22px;border-radius:11px;background:#cbd5e1;padding:2px;cursor:pointer;transition:all 0.2s;}.cd{display:flex;flex-direction:column;width:18px;height:18px;border-radius:50%;background:white;transition:all 0.2s;}.ce{display:flex;flex-direction:column;margin-top:24px;}.cf{display:flex;flex-direction:row;gap:16px;margin-bottom:12px;align-items:center;}.cg{padding:8px 12px;border-radius:6px;border:1px solid var(--border);width:240px;}.ch{padding:6px 12px;border-radius:4px;border:1px solid var(--border);background:white;color:var(--gray);font-size:13px;cursor:pointer;transition:all 0.15s;}.ci{display:flex;flex-direction:row;gap:0;padding:8px 16px;background:var(--light);border-bottom:2px solid var(--border);border-radius:6px 6px 0 0;}.cj{display:flex;flex-direction:column;width:60px;}.ck{display:flex;flex-direction:row;gap:0;padding:10px 16px;border-bottom:1px solid var(--border);cursor:pointer;transition:all 0.1s;}.cl{flex-direction:column;width:24px;height:24px;border-radius:50%;background:var(--primary);color:white;display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:bold;}.cm{font-size:14px;color:var(--dark);}.cn{flex-direction:column;display:inline-block;padding:2px 8px;background:var(--secondary);color:white;border-radius:12px;font-size:12px;}.co{display:flex;flex-direction:row;gap:16px;padding:12px 16px;align-items:center;border-top:1px solid var(--border);}.cp{display:flex;flex-direction:row;gap:4px;}.cq{padding:6px 10px;border-radius:4px;border:1px solid var(--border);background:white;color:var(--gray);font-size:13px;cursor:pointer;}.cr{padding:6px 10px;border-radius:4px;border:1px solid var(--primary);background:var(--primary);color:white;font-size:13px;cursor:pointer;}.cs{display:flex;flex-direction:column;padding:24px 24px;background:white;border-top:1px solid var(--border);}.ct{display:flex;flex-direction:row;gap:24px;}.cu{display:flex;flex-direction:column;gap:8px;flex:1;min-width:0;}.cv{font-weight:bold;font-size:14px;color:var(--dark);}.cw{font-weight:bold;font-size:12px;color:var(--gray);text-transform:uppercase;margin-bottom:4px;}.cx{color:var(--gray);font-size:13px;}.l:hover{color:var(--primary);background:#f1f5f9;}.ab:hover,.cx:hover{color:var(--primary);}.aj:hover,.am:hover,.b0:hover,.b1:hover,.b2:hover{background:var(--dark);}.aw:hover{box-shadow:0 4 12 rgba(0,0,0,0.1);}.a0:hover,.a1:hover,.a2:hover,.a3:hover,.a4:hover,.a5:hover,.a6:hover,.a7:hover,.a8:hover,.a9:hover,.ba:hover,.bb:hover{background:#2563eb;}.bd:hover,.bo:hover,.ck:hover{background:var(--light);}.b3:hover{background:#f1f5f9;}.ch:hover{background:#f1f5f9;color:var(--dark);}.ah:focus{border:1px solid var(--primary);}@media(min-width:640px){.aq,.ct{flex-direction:column;}.bz{flex:1;min-width:0;}}@media(min-width:1024px){.aq,.ct{flex-direction:row;}}@media(prefers-color-scheme:dark){.b{background:#0f172a;border-right:1px solid var(--dark);}.f,.v,.ad,.ae,.at,.ax,.bg,.br,.by,.cm,.cv{color:white;}.h,.bs{background:#334155;}.k,.bw{background:#1e3a5f;}.s,.ch,.cq{background:var(--dark);}.x,.az,.bj,.ci{background:#0f172a;}.y{background:#0f172a;border-bottom:1px solid var(--dark);}.ah{border:1px solid #334155;background:var(--dark);color:white;}.ar,.aw{background:var(--dark);border:1px solid #334155;}.bo,.b8,.ck{border-bottom:1px solid #334155;}.b7{background:#334155;color:#94a3b8;}.cc{background:#475569;}.cs{background:#0f172a;border-top:1px solid var(--dark);}}}@keyframes fade-in {from{opacity:0}to{opacity:1}}@keyframes slide-down {0%{transform:translateY(-10px);opacity:0}100%{transform:translateY(0);opacity:1}}</style></head><body><div class="a"><div class="b"><div class="c"><div class="d"><span>HL</span></div><div class="e"><span class="f">htmlang</span><span class="g">Dashboard v2.0</span></div></div><div class="h"></div><div class="i"><span class="j">Navigation</span><div class="e"><a href="/dashboard" class="k">Dashboard</a><a href="/analytics" class="l">Analytics</a><a href="/projects" class="l">Projects</a><a href="/team" class="l">Team</a><a href="/messages" class="l">Messages</a><a href="/calendar" class="l">Calendar</a><a href="/documents" class="l">Documents</a><a href="/settings" class="l">Settings</a></div></div><div class="i"><span class="j">Favorites</span><div class="e"><a href="/project/alpha" class="l">Project Alpha</a><a href="/project/beta" class="l">Project Beta</a><a href="/reports/q4" class="l">Q4 Reports</a></div></div><div class="i"><span class="j">Shortcuts</span><div class="m"><div class="n"><div class="o"></div><span class="p">Online (12)</span></div><div class="n"><div class="q"></div><span class="p">Away (3)</span></div><div class="n"><div class="r"></div><span class="p">Offline (5)</span></div></div></div><div class="s"><div class="n"><div class="t"><span>JD</span></div><div class="u"><span class="v">Jane Doe</span><span class="w">jane@example.com</span></div></div></div></div><div class="x"><header class="y"><div class="z"><div class="e"><div class="aa"><div class="aa"><a href="/" class="ab">Home</a><span class="ac">/</span></div><span class="ad">Dashboard</span></div><span class="ae">Dashboard Overview</span></div><div class="af"></div><div class="ag"><input class="ah" type="search" placeholder="Search..."><div class="ai"><button class="aj">Alerts</button><div class="ak"><div class="al"></div></div></div><button class="am">Settings</button></div></div></header><div class="an"><div class="ao"><span class="ap">Welcome back! You have 3 new notifications and 2 pending tasks.</span></div><div class="aq"><div class="ar"><span class="as">Total Revenue</span><span class="at">$48</span><span class="au">+12.5% from last month</span></div><div class="ar"><span class="as">Active Users</span><span class="at">2</span><span class="au">+8.2% from last week</span></div><div class="ar"><span class="as">Conversion Rate</span><span class="at">3.24%</span><span class="au">+0.4% from yesterday</span></div><div class="ar"><span class="as">Open Tickets</span><span class="at">142</span><span class="au">-5.1% from last month</span></div></div><div class="av"><div class="aw"><span class="ax">Revenue Overview</span><div class="ay"><div class="az"><div class="a0"></div><div class="a1"></div><div class="a2"></div><div class="a3"></div><div class="a4"></div><div class="a5"></div><div class="a6"></div><div class="a7"></div><div class="a8"></div><div class="a9"></div><div class="ba"></div><div class="bb"></div></div></div></div><div class="aw"><span class="ax">Activity Feed</span><div class="ay"><div class="bc"><div class="bd"><div class="be"><span>Alice</span></div><div class="bf"><span class="bg">Alice</span><span class="g">Updated project files</span></div><span class="w">2h ago</span></div><div class="bd"><div class="be"><span>Bob</span></div><div class="bf"><span class="bg">Bob</span><span class="g">Updated project files</span></div><span class="w">2h ago</span></div><div class="bd"><div class="be"><span>Carol</span></div><div class="bf"><span class="bg">Carol</span><span class="g">Updated project files</span></div><span class="w">2h ago</span></div><div class="bd"><div class="be"><span>Dave</span></div><div class="bf"><span class="bg">Dave</span><span class="g">Updated project files</span></div><span class="w">2h ago</span></div><div class="bd"><div class="be"><span>Eve</span></div><div class="bf"><span class="bg">Eve</span><span class="g">Updated project files</span></div><span class="w">2h ago</span></div><div class="bd"><div class="be"><span>Frank</span></div><div class="bf"><span class="bg">Frank</span><span class="g">Updated project files</span></div><span class="w">2h ago</span></div><div class="bd"><div class="be"><span>Grace</span></div><div class="bf"><span class="bg">Grace</span><span class="g">Updated project files</span></div><span class="w">2h ago</span></div><div class="bd"><div class="be"><span>Hank</span></div><div class="bf"><span class="bg">Hank</span><span class="g">Updated project files</span></div><span class="w">2h ago</span></div></div></div></div></div><div class="aq"><div class="bh"><div class="aw"><span class="ax">Project Status</span><div class="ay"><div class="bi"><div class="bj"><div class="bk"><span class="bl">Project</span></div><div class="bm"><span class="bl">Status</span></div><div class="bn"><span class="bl">Progress</span></div><div class="af"><span class="bl">Due Date</span></div></div><div class="bo"><div class="bk"><span class="bp">Project Alpha</span></div><div class="bm"><span class="as">In Progress</span></div><div class="bn"><span class="bp">75%</span></div><div class="af"><span class="as">Dec 15 2025</span></div></div><div class="bo"><div class="bk"><span class="bp">Project Beta</span></div><div class="bm"><span class="as">Review</span></div><div class="bn"><span class="bp">90%</span></div><div class="af"><span class="as">Nov 30 2025</span></div></div><div class="bo"><div class="bk"><span class="bp">Project Gamma</span></div><div class="bm"><span class="as">Planning</span></div><div class="bn"><span class="bp">20%</span></div><div class="af"><span class="as">Jan 20 2026</span></div></div><div class="bo"><div class="bk"><span class="bp">Project Delta</span></div><div class="bm"><span class="as">Completed</span></div><div class="bn"><span class="bp">100%</span></div><div class="af"><span class="as">Oct 10 2025</span></div></div><div class="bo"><div class="bk"><span class="bp">Project Epsilon</span></div><div class="bm"><span class="as">On Hold</span></div><div class="bn"><span class="bp">45%</span></div><div class="af"><span class="as">Feb 28 2026</span></div></div></div></div></div><div class="aw"><span class="ax">Progress Breakdown</span><div class="ay"><div class="bc"><div class="m"><div class="bq"><span class="br">Alpha</span><span class="p">67%</span></div><div class="bs"><div class="bt"></div></div></div><div class="m"><div class="bq"><span class="br">Beta</span><span class="p">67%</span></div><div class="bs"><div class="bt"></div></div></div><div class="m"><div class="bq"><span class="br">Gamma</span><span class="p">67%</span></div><div class="bs"><div class="bt"></div></div></div><div class="m"><div class="bq"><span class="br">Delta</span><span class="p">67%</span></div><div class="bs"><div class="bt"></div></div></div><div class="m"><div class="bq"><span class="br">Epsilon</span><span class="p">67%</span></div><div class="bs"><div class="bt"></div></div></div></div></div></div><div class="aw"><span class="ax">Recent Activity Log</span><div class="ay"><div class="bu"><div class="bv"><div class="bw"><span class="bx">0</span></div><span class="by">Deployed v2.3.1 to production</span><span class="w">just now</span></div><div class="bv"><div class="bw"><span class="bx">1</span></div><span class="by">Merged feature/auth-redesign</span><span class="w">just now</span></div><div class="bv"><div class="bw"><span class="bx">2</span></div><span class="by">Closed issue #482: Login timeout</span><span class="w">just now</span></div><div class="bv"><div class="bw"><span class="bx">3</span></div><span class="by">Updated CI/CD pipeline config</span><span class="w">just now</span></div><div class="bv"><div class="bw"><span class="bx">4</span></div><span class="by">Added unit tests for payment module</span><span class="w">just now</span></div><div class="bv"><div class="bw"><span class="bx">5</span></div><span class="by">Reviewed PR #156: API refactor</span><span class="w">just now</span></div><div class="bv"><div class="bw"><span class="bx">6</span></div><span class="by">Fixed memory leak in worker pool</span><span class="w">just now</span></div><div class="bv"><div class="bw"><span class="bx">7</span></div><span class="by">Released hotfix 2.3.2</span><span class="w">just now</span></div></div></div></div></div><div class="bz"><div class="aw"><span class="ax">Quick Actions</span><div class="ay"><div class="bu"><button class="aj">New Project</button><button class="b0">Create Report</button><button class="b1">Invite Member</button><button class="b2">View Backlog</button></div></div></div><div class="aw"><span class="ax">Team Members</span><div class="ay"><div class="bu"><div class="b3"><div class="t"><span>Alice</span></div><div class="b4"><span class="v">Alice</span><span class="w">Developer</span></div><div class="b5"></div></div><div class="b3"><div class="t"><span>Bob</span></div><div class="b4"><span class="v">Bob</span><span class="w">Developer</span></div><div class="b5"></div></div><div class="b3"><div class="t"><span>Carol</span></div><div class="b4"><span class="v">Carol</span><span class="w">Developer</span></div><div class="b5"></div></div><div class="b3"><div class="t"><span>Dave</span></div><div class="b4"><span class="v">Dave</span><span class="w">Developer</span></div><div class="b5"></div></div><div class="b3"><div class="t"><span>Eve</span></div><div class="b4"><span class="v">Eve</span><span class="w">Developer</span></div><div class="b5"></div></div><div class="b3"><div class="t"><span>Frank</span></div><div class="b4"><span class="v">Frank</span><span class="w">Developer</span></div><div class="b5"></div></div><div class="b3"><div class="t"><span>Grace</span></div><div class="b4"><span class="v">Grace</span><span class="w">Developer</span></div><div class="b5"></div></div><div class="b3"><div class="t"><span>Hank</span></div><div class="b4"><span class="v">Hank</span><span class="w">Developer</span></div><div class="b5"></div></div></div></div></div><div class="aw"><span class="ax">Tags</span><div class="ay"><div class="b6"><div class="b7"><span>frontend</span></div><div class="b7"><span>backend</span></div><div class="b7"><span>devops</span></div><div class="b7"><span>design</span></div><div class="b7"><span>mobile</span></div><div class="b7"><span>security</span></div><div class="b7"><span>performance</span></div><div class="b7"><span>testing</span></div><div class="b7"><span>docs</span></div><div class="b7"><span>infra</span></div><div class="b7"><span>ux</span></div><div class="b7"><span>api</span></div></div></div></div><div class="aw"><span class="ax">Notifications</span><div class="ay"><div class="bi"><div class="b8"><div class="al"></div><span class="br">New deployment completed</span><span class="w">now</span></div><div class="b8"><div class="al"></div><span class="br">PR review requested</span><span class="w">now</span></div><div class="b8"><div class="al"></div><span class="br">Build failed on staging</span><span class="w">now</span></div><div class="b8"><div class="al"></div><span class="br">Meeting in 30 minutes</span><span class="w">now</span></div><div class="b8"><div class="al"></div><span class="br">Subscription renewal due</span><span class="w">now</span></div></div></div></div><div class="aw"><span class="ax">Settings</span><div class="ay"><div class="bc"><div class="b9"><span class="by">Dark Mode</span><div class="ca"><div class="cb"></div></div></div><div class="b9"><span class="by">Notifications</span><div class="ca"><div class="cb"></div></div></div><div class="b9"><span class="by">Auto-save</span><div class="cc"><div class="cd"></div></div></div><div class="b9"><span class="by">Compact View</span><div class="cc"><div class="cd"></div></div></div></div></div></div></div></div><div class="ce"><div class="aw"><span class="ax">Data Table</span><div class="ay"><div class="bi"><div class="cf"><input class="cg" type="search" placeholder="Filter results..."><div class="af"></div><div class="aa"><button class="ch">all</button><button class="ch">design</button><button class="ch">development</button><button class="ch">marketing</button><button class="ch">analytics</button></div></div><div class="ci"><div class="cj"><span class="bl">ID</span></div><div class="bk"><span class="bl">Name</span></div><div class="bm"><span class="bl">Category</span></div><div class="bn"><span class="bl">Status</span></div><div class="af"><span class="bl">Updated</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Alpha</span></div><span class="cm">Alpha</span></div></div><div class="bm"><span class="p">active</span></div><div class="bn"><div class="cn"><span>active</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Beta</span></div><span class="cm">Beta</span></div></div><div class="bm"><span class="p">active</span></div><div class="bn"><div class="cn"><span>active</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Gamma</span></div><span class="cm">Gamma</span></div></div><div class="bm"><span class="p">active</span></div><div class="bn"><div class="cn"><span>active</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Delta</span></div><span class="cm">Delta</span></div></div><div class="bm"><span class="p">active</span></div><div class="bn"><div class="cn"><span>active</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Epsilon</span></div><span class="cm">Epsilon</span></div></div><div class="bm"><span class="p">active</span></div><div class="bn"><div class="cn"><span>active</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Alpha</span></div><span class="cm">Alpha</span></div></div><div class="bm"><span class="p">pending</span></div><div class="bn"><div class="cn"><span>pending</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Beta</span></div><span class="cm">Beta</span></div></div><div class="bm"><span class="p">pending</span></div><div class="bn"><div class="cn"><span>pending</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Gamma</span></div><span class="cm">Gamma</span></div></div><div class="bm"><span class="p">pending</span></div><div class="bn"><div class="cn"><span>pending</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Delta</span></div><span class="cm">Delta</span></div></div><div class="bm"><span class="p">pending</span></div><div class="bn"><div class="cn"><span>pending</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Epsilon</span></div><span class="cm">Epsilon</span></div></div><div class="bm"><span class="p">pending</span></div><div class="bn"><div class="cn"><span>pending</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Alpha</span></div><span class="cm">Alpha</span></div></div><div class="bm"><span class="p">completed</span></div><div class="bn"><div class="cn"><span>completed</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Beta</span></div><span class="cm">Beta</span></div></div><div class="bm"><span class="p">completed</span></div><div class="bn"><div class="cn"><span>completed</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Gamma</span></div><span class="cm">Gamma</span></div></div><div class="bm"><span class="p">completed</span></div><div class="bn"><div class="cn"><span>completed</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Delta</span></div><span class="cm">Delta</span></div></div><div class="bm"><span class="p">completed</span></div><div class="bn"><div class="cn"><span>completed</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Epsilon</span></div><span class="cm">Epsilon</span></div></div><div class="bm"><span class="p">completed</span></div><div class="bn"><div class="cn"><span>completed</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Alpha</span></div><span class="cm">Alpha</span></div></div><div class="bm"><span class="p">archived</span></div><div class="bn"><div class="cn"><span>archived</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Beta</span></div><span class="cm">Beta</span></div></div><div class="bm"><span class="p">archived</span></div><div class="bn"><div class="cn"><span>archived</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Gamma</span></div><span class="cm">Gamma</span></div></div><div class="bm"><span class="p">archived</span></div><div class="bn"><div class="cn"><span>archived</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Delta</span></div><span class="cm">Delta</span></div></div><div class="bm"><span class="p">archived</span></div><div class="bn"><div class="cn"><span>archived</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Epsilon</span></div><span class="cm">Epsilon</span></div></div><div class="bm"><span class="p">archived</span></div><div class="bn"><div class="cn"><span>archived</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="co"><span class="p">Showing 1-20 of 142 results</span><div class="af"></div><div class="cp"><button class="cq">Prev</button><button class="cr">1</button><button class="cq">2</button><button class="cq">3</button><button class="cq">Next</button></div></div></div></div></div></div></div><footer class="cs"><div class="ct"><div class="cu"><span class="cv">htmlang Dashboard</span><span class="g">Built with htmlang - a declarative HTML language</span><span class="w">Copyright 2025 htmlang contributors</span></div><div class="m"><span class="cw">Product</span><a href="/features" class="cx">Features</a><a href="/pricing" class="cx">Pricing</a><a href="/changelog" class="cx">Changelog</a><a href="/roadmap" class="cx">Roadmap</a></div><div class="m"><span class="cw">Resources</span><a href="/docs" class="cx">Documentation</a><a href="/api" class="cx">API Reference</a><a href="/guides" class="cx">Guides</a><a href="/examples" class="cx">Examples</a></div><div class="m"><span class="cw">Company</span><a href="/about" class="cx">About</a><a href="/blog" class="cx">Blog</a><a href="/careers" class="cx">Careers</a><a href="/contact" class="cx">Contact</a></div><div class="m"><span class="cw">Legal</span><a href="/privacy" class="cx">Privacy Policy</a><a href="/terms" class="cx">Terms of Service</a><a href="/cookies" class="cx">Cookie Policy</a></div></div></footer></div></div></body></html>
tests/snapshots/translations_i18n.hl+1−1
@@ -1,6 +1,6 @@
11@let t.greeting Hello
22@let t.farewell Goodbye
33
4−@column [padding 20]
4+@el [padding 20]
55 @text $t.greeting
66 @text $t.farewell
tests/snapshots/variable_filters.hl+1−1
@@ -2,7 +2,7 @@
22@let name hello world
33@let greeting hi
44
5−@column [spacing 10]
5+@el [spacing 10]
66 @text ${uppercase($name)}
77 @text ${lowercase($name)}
88 @text ${capitalize($name)}
tests/snapshots/variables_defines.hl+1−1
@@ -3,7 +3,7 @@
33@let gap 20
44@let card-style [padding 20, border-radius 8, background white]
55
6−@column [spacing $gap]
6+@el [spacing $gap]
77 @el [$card-style]
88 @text [color $primary] Hello
99 @el [$card-style, border 1 solid $primary]
tests/snapshots/view_transitions.hl+1−1
@@ -1,5 +1,5 @@
11@page View Transitions
2−@column [spacing 20, padding 20]
2+@el [spacing 20, padding 20]
33 @el [view-transition-name hero, padding 20, background #3b82f6, color white, border-radius 8]
44 Hero element
55 @el [view-transition-name sidebar, padding 10]