feat: create Lux website with sleek/noble aesthetic

Website design:
- Translucent black (#0a0a0a) with gold (#d4af37) accents
- Strong serif typography (Playfair Display, Source Serif Pro)
- Glass-morphism cards with gold borders
- Responsive layout with elegant animations

Content:
- Landing page with hero, code demo, value props, benchmarks
- Effects-focused messaging ("No surprises. No hidden side effects.")
- Performance benchmarks showing Lux matches C
- Quick start guide

Technical:
- Added HTML rendering functions to stdlib/html.lux
- Created Lux-based site generator (blocked by module import issues)
- Documented Lux weaknesses discovered during development:
  - Module import system not working
  - FileSystem effect incomplete
  - No template string support

The landing page HTML/CSS is complete and viewable.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-16 06:41:49 -05:00
parent 49ab70829a
commit 552e7a4972
10 changed files with 3046 additions and 269 deletions

View File

@@ -296,3 +296,89 @@ fn when<M>(condition: Bool, element: Html<M>): Html<M> =
// Conditionally apply attributes
fn attrIf<M>(condition: Bool, attr: Attr<M>): List<Attr<M>> =
if condition then [attr] else []
// ============================================================================
// Static HTML Rendering (for SSG)
// ============================================================================
// Render an attribute to a string
fn renderAttr<M>(attr: Attr<M>): String =
match attr {
Class(name) => " class=\"" + name + "\"",
Id(name) => " id=\"" + name + "\"",
Style(prop, val) => " style=\"" + prop + ": " + val + "\"",
Href(url) => " href=\"" + url + "\"",
Src(url) => " src=\"" + url + "\"",
Alt(desc) => " alt=\"" + desc + "\"",
Type(t) => " type=\"" + t + "\"",
Value(v) => " value=\"" + v + "\"",
Placeholder(p) => " placeholder=\"" + p + "\"",
Disabled(true) => " disabled",
Disabled(false) => "",
Checked(true) => " checked",
Checked(false) => "",
Name(n) => " name=\"" + n + "\"",
DataAttr(name, value) => " data-" + name + "=\"" + value + "\"",
// Event handlers are ignored in static rendering
OnClick(_) => "",
OnInput(_) => "",
OnSubmit(_) => "",
OnChange(_) => "",
OnMouseEnter(_) => "",
OnMouseLeave(_) => "",
OnFocus(_) => "",
OnBlur(_) => "",
OnKeyDown(_) => "",
OnKeyUp(_) => ""
}
// Render attributes list to string
fn renderAttrs<M>(attrs: List<Attr<M>>): String =
List.foldl(attrs, "", fn(acc, attr) => acc + renderAttr(attr))
// Self-closing tags
fn isSelfClosing(tag: String): Bool =
tag == "br" || tag == "hr" || tag == "img" || tag == "input" ||
tag == "meta" || tag == "link" || tag == "area" || tag == "base" ||
tag == "col" || tag == "embed" || tag == "source" || tag == "track" || tag == "wbr"
// Render Html to string
fn render<M>(html: Html<M>): String =
match html {
Element(tag, attrs, children) => {
let attrStr = renderAttrs(attrs)
if isSelfClosing(tag) then
"<" + tag + attrStr + " />"
else {
let childrenStr = List.foldl(children, "", fn(acc, child) => acc + render(child))
"<" + tag + attrStr + ">" + childrenStr + "</" + tag + ">"
}
},
Text(content) => escapeHtml(content),
Empty => ""
}
// Escape HTML special characters
fn escapeHtml(s: String): String = {
// Simple replacement - a full implementation would handle all entities
let s1 = String.replace(s, "&", "&amp;")
let s2 = String.replace(s1, "<", "&lt;")
let s3 = String.replace(s2, ">", "&gt;")
let s4 = String.replace(s3, "\"", "&quot;")
s4
}
// Render a full HTML document
fn document(title: String, headExtra: List<Html<M>>, bodyContent: List<Html<M>>): String = {
let headElements = List.concat([
[Element("meta", [DataAttr("charset", "UTF-8")], [])],
[Element("meta", [Name("viewport"), Value("width=device-width, initial-scale=1.0")], [])],
[Element("title", [], [Text(title)])],
headExtra
])
let doc = Element("html", [DataAttr("lang", "en")], [
Element("head", [], headElements),
Element("body", [], bodyContent)
])
"<!DOCTYPE html>\n" + render(doc)
}