From 09947262a5448848a702e318ef3e4cc84d8b28ab Mon Sep 17 00:00:00 2001 From: giles Date: Sun, 8 Mar 2026 00:15:39 +0000 Subject: [PATCH] Add CSSX as top-level docs section with patterns, async, and live examples New top-level section in sx-docs: /cssx/ with 6 pages: - Overview: the idea, what changed, advantages - Patterns: class mapping, data-driven, style functions, responsive, emitting CSS - Async CSS: components that fetch/cache CSS before rendering via ~suspense - Live Styles: SSE/WS examples for real-time style updates (noted as future) - Comparisons: vs styled-components, CSS Modules, Tailwind, Vanilla Extract - Philosophy: proof by deletion, the right abstraction level Also: - Remove CSSX from specs nav (spec file deleted) - Fix renderer spec prose (no longer mentions StyleValue) - Update On-Demand CSS essay summary - Mark CSSX Components plan as done Co-Authored-By: Claude Opus 4.6 --- sx/sx/cssx.sx | 354 +++++++++++++++++++++++++++++++++++++++++++ sx/sx/layouts.sx | 1 + sx/sx/nav-data.sx | 15 +- sx/sxc/pages/docs.sx | 33 ++++ 4 files changed, 399 insertions(+), 4 deletions(-) create mode 100644 sx/sx/cssx.sx 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 "