diff --git a/sx/sx/cssx.sx b/sx/sx/cssx.sx new file mode 100644 index 0000000..20e2d1b --- /dev/null +++ b/sx/sx/cssx.sx @@ -0,0 +1,354 @@ +;; CSSX — Styling as Components +;; Documentation for the CSSX approach: no parallel style infrastructure, +;; just defcomp components that decide how to style their children. + +;; --------------------------------------------------------------------------- +;; Overview +;; --------------------------------------------------------------------------- + +(defcomp ~cssx-overview-content () + (~doc-page :title "CSSX Components" + + (~doc-section :title "The Idea" :id "idea" + (p (strong "Styling is just components.") " A CSSX component is a regular " + (code "defcomp") " that decides how to style its children. It might apply " + "Tailwind classes, or hand-written CSS classes, or inline styles, or generate " + "rules at runtime. The implementation is the component's private business. " + "The consumer just calls " (code "(~btn :variant \"primary\" \"Submit\")") " and doesn't care.") + (p "Because it's " (code "defcomp") ", you get everything for free: caching, bundling, " + "dependency scanning, server/client rendering, composition. No parallel infrastructure.")) + + (~doc-section :title "Why Not a Style Dictionary?" :id "why" + (p "SX previously had a parallel CSS system: a style dictionary (JSON blob of " + "atom-to-declaration mappings), a " (code "StyleValue") " type threaded through " + "the evaluator and renderer, content-addressed hash class names (" (code "sx-a3f2b1") + "), runtime CSS injection, and a separate caching pipeline (cookies, localStorage).") + (p "This was ~3,000 lines of code across the spec, bootstrappers, and host implementations. " + "It was never adopted. The codebase voted with its feet: " (code ":class") " strings " + "with " (code "defcomp") " already covered every real use case.") + (p "The result of that system: elements in the DOM got opaque class names like " + (code "class=\"sx-a3f2b1\"") ". DevTools became useless. You couldn't inspect an " + "element and understand its styling. " (strong "That was a deal breaker."))) + + (~doc-section :title "Key Advantages" :id "advantages" + (ul :class "list-disc pl-5 space-y-2 text-stone-700" + (li (strong "Readable DOM: ") "Elements have real class names, not content-addressed " + "hashes. DevTools works.") + (li (strong "Data-driven styling: ") "Components receive data and decide styling. " + (code "(~metric :value 150)") " renders red because " (code "value > 100") + " — logic lives in the component, not a CSS preprocessor.") + (li (strong "One system: ") "No separate " (code "StyleValue") " type, no style " + "dictionary JSON, no injection pipeline. Components ARE the styling abstraction.") + (li (strong "One cache: ") "Component hash/localStorage handles everything. No " + "separate style dict caching.") + (li (strong "Composable: ") (code "(~card :elevated true (~metric :value v))") + " — styling composes like any other component.") + (li (strong "Strategy-agnostic: ") "A component can apply Tailwind classes, emit " + (code "