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:
@@ -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, "&", "&")
|
||||
let s2 = String.replace(s1, "<", "<")
|
||||
let s3 = String.replace(s2, ">", ">")
|
||||
let s4 = String.replace(s3, "\"", """)
|
||||
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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user