;; Protocol documentation pages — fully self-contained
(defcomp ()
  (~docs/page :title "Wire Format"
    (~docs/section :title "The text/sx content type" :id "content-type"
      (p (~tw :tokens "text-stone-600")
        "sx responses use content type text/sx. The body is s-expression source code. The client parses and evaluates it, then renders the result into the DOM.")
      (~docs/code :src (highlight "HTTP/1.1 200 OK\nContent-Type: text/sx\nSX-Css-Hash: a1b2c3d4\n\n(div :class \"p-4\"\n  (~card :title \"Hello\"))" "bash")))
    (~docs/section :title "Request lifecycle" :id "lifecycle"
      (p (~tw :tokens "text-stone-600")
        "1. User interacts with an element that has sx-get/sx-post/etc.")
      (p (~tw :tokens "text-stone-600")
        "2. sx.js fires sx:beforeRequest, then sends the HTTP request with SX-Request: true header.")
      (p (~tw :tokens "text-stone-600")
        "3. Server builds s-expression tree, scans CSS classes, prepends missing component definitions.")
      (p (~tw :tokens "text-stone-600")
        "4. Client receives text/sx response, parses it, evaluates it, renders to DOM.")
      (p (~tw :tokens "text-stone-600")
        "5. sx.js fires sx:afterSwap and sx:afterSettle.")
      (p (~tw :tokens "text-stone-600")
        "6. Any sx-swap-oob elements are swapped into their targets elsewhere in the DOM."))
    (~docs/section :title "Component definitions" :id "components"
      (p (~tw :tokens "text-stone-600")
        "On full page loads, component definitions are in <script type=\"text/sx\" data-components>. On subsequent sx requests, missing definitions are prepended to the response body. The client caches definitions in localStorage keyed by a content hash."))))
