@@ -322,11 +322,16 @@ fn directive_completions(range: Range) -> Vec<CompletionItem> {
322 ("@page", "Set HTML page title", "@page "),
322 ("@page", "Set HTML page title", "@page "),
323 ("@let", "Define a variable", "@let "),
323 ("@let", "Define a variable", "@let "),
324 ("@define", "Define an attribute bundle", "@define "),
324 ("@define", "Define an attribute bundle", "@define "),
325− ("@fn", "Define a reusable function", "@fn "),
325+ ("@fn", "Define a reusable function (supports $param=default)", "@fn "),
326 ("@keyframes", "Define a CSS animation", "@keyframes "),
326 ("@keyframes", "Define a CSS animation", "@keyframes "),
327 ("@if", "Conditional rendering", "@if "),
327 ("@if", "Conditional rendering", "@if "),
328+ ("@else if", "Else-if branch", "@else if "),
329+ ("@else", "Else branch", "@else"),
328− ("@each", "Loop over comma-separated values", "@each "),
330+ ("@each", "Loop over values (@each $var, $i in list)", "@each "),
329− ("@include", "Include another .hl file", "@include "),
331+ ("@include", "Include another .hl file (DOM + definitions)", "@include "),
332+ ("@import", "Import definitions only (no DOM nodes)", "@import "),
333+ ("@meta", "Add a <meta> tag to <head>", "@meta "),
334+ ("@head", "Add raw content to <head>", "@head"),
332 .map(|(name, detail, insert)| {
337 .map(|(name, detail, insert)| {
@@ -338,17 +343,18 @@ fn directive_completions(range: Range) -> Vec<CompletionItem> {
338fn attr_completions(range: Range) -> Vec<CompletionItem> {
343fn attr_completions(range: Range) -> Vec<CompletionItem> {
340 // Layout
345 // Layout
341− ("spacing", "Gap between children (px)", true),
346+ ("spacing", "Gap between children (supports CSS units)", true),
347+ ("gap", "Gap between children (alias for spacing)", true),
342− ("padding", "Inner padding (1/2/3/4 values, px)", true),
348+ ("padding", "Inner padding (1/2/3/4 values, supports CSS units)", true),
343− ("padding-x", "Horizontal padding (px)", true),
349+ ("padding-x", "Horizontal padding", true),
344− ("padding-y", "Vertical padding (px)", true),
350+ ("padding-y", "Vertical padding", true),
345 // Sizing
351 // Sizing
346− ("width", "Width (px | fill | shrink)", true),
352+ ("width", "Width (px/% | fill | shrink)", true),
347− ("height", "Height (px | fill | shrink)", true),
353+ ("height", "Height (px/% | fill | shrink)", true),
348− ("min-width", "Minimum width (px)", true),
354+ ("min-width", "Minimum width", true),
349− ("max-width", "Maximum width (px)", true),
355+ ("max-width", "Maximum width", true),
350− ("min-height", "Minimum height (px)", true),
356+ ("min-height", "Minimum height", true),
351− ("max-height", "Maximum height (px)", true),
357+ ("max-height", "Maximum height", true),
352 // Alignment
358 // Alignment
353 ("center-x", "Center horizontally", false),
359 ("center-x", "Center horizontally", false),
354 ("center-y", "Center vertically", false),
360 ("center-y", "Center vertically", false),
@@ -360,11 +366,15 @@ fn attr_completions(range: Range) -> Vec<CompletionItem> {
360 ("background", "Background color/value", true),
366 ("background", "Background color/value", true),
361 ("color", "Text color", true),
367 ("color", "Text color", true),
362 ("border", "Border (width [color])", true),
368 ("border", "Border (width [color])", true),
369+ ("border-top", "Top border (width [color])", true),
370+ ("border-bottom", "Bottom border (width [color])", true),
371+ ("border-left", "Left border (width [color])", true),
372+ ("border-right", "Right border (width [color])", true),
363− ("rounded", "Border radius (px)", true),
373+ ("rounded", "Border radius", true),
364 ("bold", "Bold text", false),
374 ("bold", "Bold text", false),
365 ("italic", "Italic text", false),
375 ("italic", "Italic text", false),
366 ("underline", "Underlined text", false),
376 ("underline", "Underlined text", false),
367− ("size", "Font size (px)", true),
377+ ("size", "Font size", true),
368 ("font", "Font family", true),
378 ("font", "Font family", true),
369 ("transition", "CSS transition", true),
379 ("transition", "CSS transition", true),
370 ("cursor", "CSS cursor type", true),
380 ("cursor", "CSS cursor type", true),
@@ -372,16 +382,35 @@ fn attr_completions(range: Range) -> Vec<CompletionItem> {
372 // Typography
382 // Typography
373 ("text-align", "Text alignment (left/center/right/justify)", true),
383 ("text-align", "Text alignment (left/center/right/justify)", true),
374 ("line-height", "Line height (unitless or px)", true),
384 ("line-height", "Line height (unitless or px)", true),
385+ ("letter-spacing", "Letter spacing", true),
386+ ("text-transform", "Text transform (uppercase/lowercase/capitalize)", true),
387+ ("white-space", "White-space behavior (nowrap/pre/normal)", true),
375 // Overflow & positioning
388 // Overflow & positioning
376 ("overflow", "Overflow behavior (hidden/scroll/auto)", true),
389 ("overflow", "Overflow behavior (hidden/scroll/auto)", true),
377 ("position", "Position type (relative/absolute/fixed/sticky)", true),
390 ("position", "Position type (relative/absolute/fixed/sticky)", true),
391+ ("top", "Top offset (for positioned elements)", true),
392+ ("right", "Right offset (for positioned elements)", true),
393+ ("bottom", "Bottom offset (for positioned elements)", true),
394+ ("left", "Left offset (for positioned elements)", true),
378 ("z-index", "Stack order (integer)", true),
395 ("z-index", "Stack order (integer)", true),
396+ // Display & visibility
397+ ("display", "Display mode (none/block/inline/flex/grid)", true),
398+ ("visibility", "Visibility (visible/hidden)", true),
399+ // Transform & filters
400+ ("transform", "CSS transform (e.g., rotate(45deg))", true),
401+ ("backdrop-filter", "Backdrop filter (e.g., blur(10px))", true),
379 // Effects
402 // Effects
380 ("shadow", "Box shadow (CSS value)", true),
403 ("shadow", "Box shadow (CSS value)", true),
382 ("wrap", "Enable flex-wrap", false),
405 ("wrap", "Enable flex-wrap", false),
383− ("gap-x", "Horizontal gap between children (px)", true),
406+ ("gap-x", "Horizontal gap between children", true),
384− ("gap-y", "Vertical gap between children (px)", true),
407+ ("gap-y", "Vertical gap between children", true),
409+ ("grid", "Enable CSS grid layout", false),
410+ ("grid-cols", "Grid columns (number or template)", true),
411+ ("grid-rows", "Grid rows (number or template)", true),
412+ ("col-span", "Span columns in grid", true),
413+ ("row-span", "Span rows in grid", true),
385 // Identity
414 // Identity
386 ("id", "HTML id attribute", true),
415 ("id", "HTML id attribute", true),
387 ("class", "HTML class attribute", true),
416 ("class", "HTML class attribute", true),
@@ -437,14 +466,19 @@ fn state_attr_completions(prefix: &str, range: Range) -> Vec<CompletionItem> {
437 ("background", "Background color/value", true),
466 ("background", "Background color/value", true),
438 ("color", "Text color", true),
467 ("color", "Text color", true),
439 ("border", "Border (width [color])", true),
468 ("border", "Border (width [color])", true),
469+ ("border-top", "Top border (width [color])", true),
470+ ("border-bottom", "Bottom border (width [color])", true),
440− ("rounded", "Border radius (px)", true),
471+ ("rounded", "Border radius", true),
441 ("bold", "Bold text", false),
472 ("bold", "Bold text", false),
442 ("italic", "Italic text", false),
473 ("italic", "Italic text", false),
443 ("underline", "Underlined text", false),
474 ("underline", "Underlined text", false),
444− ("size", "Font size (px)", true),
475+ ("size", "Font size", true),
445 ("opacity", "Opacity (0-1)", true),
476 ("opacity", "Opacity (0-1)", true),
446 ("cursor", "CSS cursor type", true),
477 ("cursor", "CSS cursor type", true),
447 ("shadow", "Box shadow (CSS value)", true),
478 ("shadow", "Box shadow (CSS value)", true),
479+ ("transform", "CSS transform", true),
480+ ("display", "Display mode", true),
481+ ("visibility", "Visibility", true),
450 .map(|(name, detail, takes_value)| {
484 .map(|(name, detail, takes_value)| {
@@ -670,20 +704,23 @@ fn hover_builtin(word: &str) -> Option<String> {
670 "@textarea" => "**@textarea** \u{2014} Multi-line text input\n\nRenders as `<textarea>`.\n\nUsage: `@textarea [name bio, rows 4] Default text`",
704 "@textarea" => "**@textarea** \u{2014} Multi-line text input\n\nRenders as `<textarea>`.\n\nUsage: `@textarea [name bio, rows 4] Default text`",
671 "@option" | "@opt" => "**@option** \u{2014} Select option\n\nRenders as `<option>`.\n\nUsage: `@option [value red] Red`",
705 "@option" | "@opt" => "**@option** \u{2014} Select option\n\nRenders as `<option>`.\n\nUsage: `@option [value red] Red`",
672 "@label" => "**@label** \u{2014} Form label\n\nRenders as `<label>`.\n\nUsage: `@label [for email] Email Address`",
706 "@label" => "**@label** \u{2014} Form label\n\nRenders as `<label>`.\n\nUsage: `@label [for email] Email Address`",
673− "@if" => "**@if** \u{2014} Conditional\n\nConditionally includes children at compile time.\n\n```\n@if $theme == dark\n @el [background #333]\n@else\n @el [background white]\n```",
707+ "@if" => "**@if** \u{2014} Conditional\n\nConditionally includes children at compile time.\n\n```\n@if $theme == dark\n @el [background #333]\n@else if $theme == light\n @el [background white]\n@else\n @el [background gray]\n```",
674− "@each" => "**@each** \u{2014} Loop\n\nRepeat children for each item in a comma-separated list.\n\n```\n@each $color in red,green,blue\n @el [background $color]\n```",
708+ "@each" => "**@each** \u{2014} Loop\n\nRepeat children for each item in a comma-separated list.\nOptional index variable.\n\n```\n@each $color, $i in red,green,blue\n @text $i: $color\n```",
675− "@include" => "**@include** \u{2014} Include file\n\nIncludes another .hl file.\n\nUsage: `@include header.hl`",
709+ "@include" => "**@include** \u{2014} Include file\n\nIncludes another .hl file (DOM nodes + definitions).\n\nUsage: `@include header.hl`",
710+ "@import" => "**@import** \u{2014} Import definitions\n\nImports `@let`, `@define`, `@fn` from another .hl file without emitting DOM nodes.\n\nUsage: `@import theme.hl`",
711+ "@meta" => "**@meta** \u{2014} Meta tag\n\nAdds a `<meta>` tag to `<head>`.\n\nUsage: `@meta description A portfolio site`",
712+ "@head" => "**@head** \u{2014} Head content\n\nAdds raw content to `<head>` (fonts, icons, etc.).\n\n```\n@head\n <link rel=\"icon\" href=\"favicon.ico\">\n```",
676 // Attributes
713 // Attributes
677− "spacing" => "**spacing** `<value>`\n\nGap between children in pixels. Maps to CSS `gap`.",
714+ "spacing" | "gap" => "**spacing** `<value>`\n\nGap between children. Supports CSS units (px, rem, em, %).\nMaps to CSS `gap`.",
678− "padding" => "**padding** `<value>` | `<y> <x>` | `<t> <h> <b>` | `<t> <r> <b> <l>`\n\nInner padding in pixels. Accepts 1, 2, 3, or 4 values.",
715+ "padding" => "**padding** `<value>` | `<y> <x>` | `<t> <h> <b>` | `<t> <r> <b> <l>`\n\nInner padding. Supports CSS units. Accepts 1\u{2013}4 values.",
679− "padding-x" => "**padding-x** `<value>`\n\nHorizontal padding (left + right) in pixels.",
716+ "padding-x" => "**padding-x** `<value>`\n\nHorizontal padding (left + right). Supports CSS units.",
680− "padding-y" => "**padding-y** `<value>`\n\nVertical padding (top + bottom) in pixels.",
717+ "padding-y" => "**padding-y** `<value>`\n\nVertical padding (top + bottom). Supports CSS units.",
681− "width" => "**width** `<px>` | `fill` | `shrink`\n\n- Number: fixed width in pixels\n- `fill`: expand to fill parent\n- `shrink`: prevent flex shrinking",
718+ "width" => "**width** `<value>` | `fill` | `shrink`\n\n- Number/unit: fixed width (e.g., `300`, `50%`, `80ch`)\n- `fill`: expand to fill parent\n- `shrink`: prevent flex shrinking",
682− "height" => "**height** `<px>` | `fill` | `shrink`\n\n- Number: fixed height in pixels\n- `fill`: expand to fill parent\n- `shrink`: prevent flex shrinking",
719+ "height" => "**height** `<value>` | `fill` | `shrink`\n\n- Number/unit: fixed height (e.g., `300`, `100vh`)\n- `fill`: expand to fill parent\n- `shrink`: prevent flex shrinking",
683− "min-width" => "**min-width** `<value>` \u{2014} Minimum width in pixels.",
720+ "min-width" => "**min-width** `<value>` \u{2014} Minimum width. Supports CSS units.",
684− "max-width" => "**max-width** `<value>` \u{2014} Maximum width in pixels.",
721+ "max-width" => "**max-width** `<value>` \u{2014} Maximum width. Supports CSS units.",
685− "min-height" => "**min-height** `<value>` \u{2014} Minimum height in pixels.",
722+ "min-height" => "**min-height** `<value>` \u{2014} Minimum height. Supports CSS units.",
686− "max-height" => "**max-height** `<value>` \u{2014} Maximum height in pixels.",
723+ "max-height" => "**max-height** `<value>` \u{2014} Maximum height. Supports CSS units.",
687 "center-x" => "**center-x**\n\nCenter horizontally.\n\nIn column parent: `align-self: center`\nOtherwise: auto margins.",
724 "center-x" => "**center-x**\n\nCenter horizontally.\n\nIn column parent: `align-self: center`\nOtherwise: auto margins.",
688 "center-y" => "**center-y**\n\nCenter vertically.\n\nIn row parent: `align-self: center`\nOtherwise: auto margins.",
725 "center-y" => "**center-y**\n\nCenter vertically.\n\nIn row parent: `align-self: center`\nOtherwise: auto margins.",
689 "align-left" => "**align-left** \u{2014} Align to the left edge.",
726 "align-left" => "**align-left** \u{2014} Align to the left edge.",
@@ -693,7 +730,11 @@ fn hover_builtin(word: &str) -> Option<String> {
693 "background" => "**background** `<color>` \u{2014} Background color or CSS background value.",
730 "background" => "**background** `<color>` \u{2014} Background color or CSS background value.",
694 "color" => "**color** `<color>` \u{2014} Text color.",
731 "color" => "**color** `<color>` \u{2014} Text color.",
695 "border" => "**border** `<width> [color]`\n\nBorder. Width in pixels, color defaults to `currentColor`.",
732 "border" => "**border** `<width> [color]`\n\nBorder. Width in pixels, color defaults to `currentColor`.",
733+ "border-top" => "**border-top** `<width> [color]` \u{2014} Top border.",
734+ "border-bottom" => "**border-bottom** `<width> [color]` \u{2014} Bottom border.",
735+ "border-left" => "**border-left** `<width> [color]` \u{2014} Left border.",
736+ "border-right" => "**border-right** `<width> [color]` \u{2014} Right border.",
696− "rounded" => "**rounded** `<value>` \u{2014} Border radius in pixels.",
737+ "rounded" => "**rounded** `<value>` \u{2014} Border radius. Supports CSS units.",
697 "bold" => "**bold** \u{2014} Bold text (`font-weight: bold`).",
738 "bold" => "**bold** \u{2014} Bold text (`font-weight: bold`).",
698 "italic" => "**italic** \u{2014} Italic text (`font-style: italic`).",
739 "italic" => "**italic** \u{2014} Italic text (`font-style: italic`).",
699 "underline" => "**underline** \u{2014} Underlined text.",
740 "underline" => "**underline** \u{2014} Underlined text.",
@@ -706,7 +747,23 @@ fn hover_builtin(word: &str) -> Option<String> {
706 "line-height" => "**line-height** `<value>` \u{2014} Line height. Unitless (e.g., `1.5`) or pixels.",
747 "line-height" => "**line-height** `<value>` \u{2014} Line height. Unitless (e.g., `1.5`) or pixels.",
707 "overflow" => "**overflow** `<value>` \u{2014} Overflow behavior (`hidden`, `scroll`, `auto`, `visible`).",
748 "overflow" => "**overflow** `<value>` \u{2014} Overflow behavior (`hidden`, `scroll`, `auto`, `visible`).",
708 "position" => "**position** `<value>` \u{2014} Position type (`relative`, `absolute`, `fixed`, `sticky`).",
749 "position" => "**position** `<value>` \u{2014} Position type (`relative`, `absolute`, `fixed`, `sticky`).",
750+ "top" => "**top** `<value>` \u{2014} Top offset for positioned elements.",
751+ "right" => "**right** `<value>` \u{2014} Right offset for positioned elements.",
752+ "bottom" => "**bottom** `<value>` \u{2014} Bottom offset for positioned elements.",
753+ "left" => "**left** `<value>` \u{2014} Left offset for positioned elements.",
709 "z-index" => "**z-index** `<value>` \u{2014} Stack order (integer).",
754 "z-index" => "**z-index** `<value>` \u{2014} Stack order (integer).",
755+ "display" => "**display** `<value>` \u{2014} Display mode (`none`, `block`, `inline`, `flex`, `grid`).",
756+ "visibility" => "**visibility** `<value>` \u{2014} Visibility (`visible`, `hidden`).",
757+ "transform" => "**transform** `<value>` \u{2014} CSS transform (e.g., `rotate(45deg)`, `scale(1.5)`).",
758+ "backdrop-filter" => "**backdrop-filter** `<value>` \u{2014} Backdrop filter (e.g., `blur(10px)`).",
759+ "letter-spacing" => "**letter-spacing** `<value>` \u{2014} Letter spacing. Supports CSS units.",
760+ "text-transform" => "**text-transform** `<value>` \u{2014} Text transform (`uppercase`, `lowercase`, `capitalize`).",
761+ "white-space" => "**white-space** `<value>` \u{2014} White-space behavior (`nowrap`, `pre`, `normal`).",
762+ "grid" => "**grid** \u{2014} Enable CSS grid layout on this element.",
763+ "grid-cols" => "**grid-cols** `<value>` \u{2014} Grid template columns. Number for equal columns, or CSS value.",
764+ "grid-rows" => "**grid-rows** `<value>` \u{2014} Grid template rows. Number for equal rows, or CSS value.",
765+ "col-span" => "**col-span** `<value>` \u{2014} Span N columns in a grid.",
766+ "row-span" => "**row-span** `<value>` \u{2014} Span N rows in a grid.",
710 "shadow" => "**shadow** `<value>` \u{2014} Box shadow. Raw CSS value (e.g., `0 2px 4px rgba(0,0,0,0.1)`).",
767 "shadow" => "**shadow** `<value>` \u{2014} Box shadow. Raw CSS value (e.g., `0 2px 4px rgba(0,0,0,0.1)`).",
711 "gap-x" => "**gap-x** `<value>` \u{2014} Horizontal gap between children in pixels. Maps to `column-gap`.",
768 "gap-x" => "**gap-x** `<value>` \u{2014} Horizontal gap between children in pixels. Maps to `column-gap`.",
712 "gap-y" => "**gap-y** `<value>` \u{2014} Vertical gap between children in pixels. Maps to `row-gap`.",
769 "gap-y" => "**gap-y** `<value>` \u{2014} Vertical gap between children in pixels. Maps to `row-gap`.",