;; SX reference — demo components for attribute detail pages
;;
;; Each attribute gets a small, focused demo showing exactly
;; what that attribute does.

;; ---------------------------------------------------------------------------
;; sx-get
;; ---------------------------------------------------------------------------

(defcomp ~ref-get-demo ()
  (div :class "space-y-3"
    (button
      :sx-get "/reference/api/time"
      :sx-target "#ref-get-result"
      :sx-swap "innerHTML"
      :class "px-4 py-2 bg-violet-600 text-white rounded hover:bg-violet-700 transition-colors text-sm"
      "Load server time")
    (div :id "ref-get-result"
      :class "p-3 rounded bg-stone-50 text-stone-400 text-sm"
      "Click to load.")))

;; ---------------------------------------------------------------------------
;; sx-post
;; ---------------------------------------------------------------------------

(defcomp ~ref-post-demo ()
  (div :class "space-y-3"
    (form
      :sx-post "/reference/api/greet"
      :sx-target "#ref-post-result"
      :sx-swap "innerHTML"
      :class "flex gap-2"
      (input :type "text" :name "name" :placeholder "Your name"
        :class "flex-1 px-3 py-2 border border-stone-300 rounded text-sm focus:outline-none focus:ring-2 focus:ring-violet-500")
      (button :type "submit"
        :class "px-4 py-2 bg-violet-600 text-white rounded hover:bg-violet-700 transition-colors text-sm"
        "Greet"))
    (div :id "ref-post-result"
      :class "p-3 rounded bg-stone-50 text-stone-400 text-sm"
      "Submit to see greeting.")))

;; ---------------------------------------------------------------------------
;; sx-put
;; ---------------------------------------------------------------------------

(defcomp ~ref-put-demo ()
  (div :id "ref-put-view"
    (div :class "flex items-center justify-between p-3 bg-stone-50 rounded"
      (span :class "text-stone-700 text-sm" "Status: " (strong "draft"))
      (button
        :sx-put "/reference/api/status"
        :sx-target "#ref-put-view"
        :sx-swap "innerHTML"
        :sx-vals "{\"status\": \"published\"}"
        :class "px-3 py-1 bg-violet-600 text-white rounded text-sm hover:bg-violet-700"
        "Publish"))))

;; ---------------------------------------------------------------------------
;; sx-delete
;; ---------------------------------------------------------------------------

(defcomp ~ref-delete-demo ()
  (div :class "space-y-2"
    (div :id "ref-del-1" :class "flex items-center justify-between p-2 border border-stone-200 rounded"
      (span :class "text-sm text-stone-700" "Item A")
      (button :sx-delete "/reference/api/item/1"
        :sx-target "#ref-del-1" :sx-swap "delete"
        :class "text-red-500 text-sm hover:text-red-700" "Remove"))
    (div :id "ref-del-2" :class "flex items-center justify-between p-2 border border-stone-200 rounded"
      (span :class "text-sm text-stone-700" "Item B")
      (button :sx-delete "/reference/api/item/2"
        :sx-target "#ref-del-2" :sx-swap "delete"
        :class "text-red-500 text-sm hover:text-red-700" "Remove"))
    (div :id "ref-del-3" :class "flex items-center justify-between p-2 border border-stone-200 rounded"
      (span :class "text-sm text-stone-700" "Item C")
      (button :sx-delete "/reference/api/item/3"
        :sx-target "#ref-del-3" :sx-swap "delete"
        :class "text-red-500 text-sm hover:text-red-700" "Remove"))))

;; ---------------------------------------------------------------------------
;; sx-patch
;; ---------------------------------------------------------------------------

(defcomp ~ref-patch-demo ()
  (div :id "ref-patch-view" :class "space-y-2"
    (div :class "p-3 bg-stone-50 rounded"
      (span :class "text-stone-700 text-sm" "Theme: " (strong :id "ref-patch-val" "light")))
    (div :class "flex gap-2"
      (button :sx-patch "/reference/api/theme"
        :sx-vals "{\"theme\": \"dark\"}"
        :sx-target "#ref-patch-val" :sx-swap "innerHTML"
        :class "px-3 py-1 bg-stone-800 text-white rounded text-sm" "Dark")
      (button :sx-patch "/reference/api/theme"
        :sx-vals "{\"theme\": \"light\"}"
        :sx-target "#ref-patch-val" :sx-swap "innerHTML"
        :class "px-3 py-1 bg-white border border-stone-300 text-stone-700 rounded text-sm" "Light"))))

;; ---------------------------------------------------------------------------
;; sx-trigger
;; ---------------------------------------------------------------------------

(defcomp ~ref-trigger-demo ()
  (div :class "space-y-3"
    (input :type "text" :name "q" :placeholder "Type to search..."
      :sx-get "/reference/api/trigger-search"
      :sx-trigger "input changed delay:300ms"
      :sx-target "#ref-trigger-result"
      :sx-swap "innerHTML"
      :class "w-full px-3 py-2 border border-stone-300 rounded text-sm focus:outline-none focus:ring-2 focus:ring-violet-500")
    (div :id "ref-trigger-result"
      :class "p-3 rounded bg-stone-50 text-stone-400 text-sm"
      "Start typing to trigger a search.")))

;; ---------------------------------------------------------------------------
;; sx-target
;; ---------------------------------------------------------------------------

(defcomp ~ref-target-demo ()
  (div :class "space-y-3"
    (div :class "flex gap-2"
      (button :sx-get "/reference/api/time"
        :sx-target "#ref-target-a"
        :sx-swap "innerHTML"
        :class "px-3 py-1 bg-violet-600 text-white rounded text-sm hover:bg-violet-700"
        "Update Box A")
      (button :sx-get "/reference/api/time"
        :sx-target "#ref-target-b"
        :sx-swap "innerHTML"
        :class "px-3 py-1 bg-emerald-600 text-white rounded text-sm hover:bg-emerald-700"
        "Update Box B"))
    (div :class "grid grid-cols-2 gap-3"
      (div :id "ref-target-a" :class "p-3 rounded border border-violet-200 bg-violet-50 text-sm text-stone-500"
        "Box A")
      (div :id "ref-target-b" :class "p-3 rounded border border-emerald-200 bg-emerald-50 text-sm text-stone-500"
        "Box B"))))

;; ---------------------------------------------------------------------------
;; sx-swap
;; ---------------------------------------------------------------------------

(defcomp ~ref-swap-demo ()
  (div :class "space-y-3"
    (div :class "flex gap-2 flex-wrap"
      (button :sx-get "/reference/api/swap-item"
        :sx-target "#ref-swap-list" :sx-swap "beforeend"
        :class "px-3 py-1 bg-violet-600 text-white rounded text-sm" "beforeend")
      (button :sx-get "/reference/api/swap-item"
        :sx-target "#ref-swap-list" :sx-swap "afterbegin"
        :class "px-3 py-1 bg-emerald-600 text-white rounded text-sm" "afterbegin")
      (button :sx-get "/reference/api/swap-item"
        :sx-target "#ref-swap-list" :sx-swap "innerHTML"
        :class "px-3 py-1 bg-blue-600 text-white rounded text-sm" "innerHTML"))
    (div :id "ref-swap-list"
      :class "p-3 rounded border border-stone-200 space-y-1 min-h-[3rem]"
      (div :class "text-sm text-stone-500" "Original item"))))

;; ---------------------------------------------------------------------------
;; sx-swap-oob
;; ---------------------------------------------------------------------------

(defcomp ~ref-oob-demo ()
  (div :class "space-y-3"
    (button :sx-get "/reference/api/oob"
      :sx-target "#ref-oob-main"
      :sx-swap "innerHTML"
      :class "px-4 py-2 bg-violet-600 text-white rounded text-sm hover:bg-violet-700"
      "Update both boxes")
    (div :class "grid grid-cols-2 gap-3"
      (div :class "rounded border border-stone-200 p-3"
        (div :class "text-xs text-stone-400 mb-1" "Main target")
        (div :id "ref-oob-main" :class "text-sm text-stone-500" "Waiting..."))
      (div :class "rounded border border-stone-200 p-3"
        (div :class "text-xs text-stone-400 mb-1" "OOB target")
        (div :id "ref-oob-side" :class "text-sm text-stone-500" "Waiting...")))))

;; ---------------------------------------------------------------------------
;; sx-select
;; ---------------------------------------------------------------------------

(defcomp ~ref-select-demo ()
  (div :class "space-y-3"
    (button :sx-get "/reference/api/select-page"
      :sx-target "#ref-select-result"
      :sx-select "#the-content"
      :sx-swap "innerHTML"
      :class "px-4 py-2 bg-violet-600 text-white rounded text-sm hover:bg-violet-700"
      "Load (selecting #the-content)")
    (div :id "ref-select-result"
      :class "p-3 rounded bg-stone-50 text-stone-400 text-sm"
      "Only the selected fragment will appear here.")))

;; ---------------------------------------------------------------------------
;; sx-confirm
;; ---------------------------------------------------------------------------

(defcomp ~ref-confirm-demo ()
  (div :class "space-y-2"
    (div :id "ref-confirm-item"
      :class "flex items-center justify-between p-3 border border-stone-200 rounded"
      (span :class "text-sm text-stone-700" "Important file.txt")
      (button :sx-delete "/reference/api/item/confirm"
        :sx-target "#ref-confirm-item" :sx-swap "delete"
        :sx-confirm "Are you sure you want to delete this file?"
        :class "px-3 py-1 text-red-500 text-sm border border-red-200 rounded hover:bg-red-50"
        "Delete"))))

;; ---------------------------------------------------------------------------
;; sx-push-url
;; ---------------------------------------------------------------------------

(defcomp ~ref-pushurl-demo ()
  (div :class "space-y-3"
    (div :class "flex gap-2"
      (a :href "/reference/attributes/sx-get"
        :sx-get "/reference/attributes/sx-get"
        :sx-target "#main-panel" :sx-select "#main-panel"
        :sx-swap "outerHTML" :sx-push-url "true"
        :class "px-3 py-1 bg-violet-100 text-violet-700 rounded text-sm no-underline hover:bg-violet-200"
        "sx-get page")
      (a :href "/reference/attributes/sx-post"
        :sx-get "/reference/attributes/sx-post"
        :sx-target "#main-panel" :sx-select "#main-panel"
        :sx-swap "outerHTML" :sx-push-url "true"
        :class "px-3 py-1 bg-violet-100 text-violet-700 rounded text-sm no-underline hover:bg-violet-200"
        "sx-post page"))
    (p :class "text-sm text-stone-500"
      "Click a link — the URL bar updates without a full page reload. Use browser back to return.")))

;; ---------------------------------------------------------------------------
;; sx-sync
;; ---------------------------------------------------------------------------

(defcomp ~ref-sync-demo ()
  (div :class "space-y-3"
    (input :type "text" :name "q" :placeholder "Type quickly..."
      :sx-get "/reference/api/slow-echo"
      :sx-trigger "input changed delay:100ms"
      :sx-sync "replace"
      :sx-target "#ref-sync-result"
      :sx-swap "innerHTML"
      :class "w-full px-3 py-2 border border-stone-300 rounded text-sm focus:outline-none focus:ring-2 focus:ring-violet-500")
    (p :class "text-xs text-stone-400"
      "With sync:replace, each new keystroke aborts the in-flight request.")
    (div :id "ref-sync-result"
      :class "p-3 rounded bg-stone-50 text-stone-400 text-sm"
      "Type to see only the latest result.")))

;; ---------------------------------------------------------------------------
;; sx-encoding
;; ---------------------------------------------------------------------------

(defcomp ~ref-encoding-demo ()
  (div :class "space-y-3"
    (form :sx-post "/reference/api/upload-name"
      :sx-encoding "multipart/form-data"
      :sx-target "#ref-encoding-result"
      :sx-swap "innerHTML"
      :class "flex gap-2"
      (input :type "file" :name "file"
        :class "flex-1 text-sm text-stone-500 file:mr-2 file:px-3 file:py-1 file:rounded file:border-0 file:text-sm file:bg-violet-50 file:text-violet-700")
      (button :type "submit"
        :class "px-4 py-2 bg-violet-600 text-white rounded text-sm hover:bg-violet-700"
        "Upload"))
    (div :id "ref-encoding-result"
      :class "p-3 rounded bg-stone-50 text-stone-400 text-sm"
      "Select a file and submit.")))

;; ---------------------------------------------------------------------------
;; sx-headers
;; ---------------------------------------------------------------------------

(defcomp ~ref-headers-demo ()
  (div :class "space-y-3"
    (button :sx-get "/reference/api/echo-headers"
      :sx-headers "{\"X-Custom-Token\": \"abc123\", \"X-Request-Source\": \"demo\"}"
      :sx-target "#ref-headers-result"
      :sx-swap "innerHTML"
      :class "px-4 py-2 bg-violet-600 text-white rounded text-sm hover:bg-violet-700"
      "Send with custom headers")
    (div :id "ref-headers-result"
      :class "p-3 rounded bg-stone-50 text-stone-400 text-sm"
      "Click to see echoed headers.")))

;; ---------------------------------------------------------------------------
;; sx-include
;; ---------------------------------------------------------------------------

(defcomp ~ref-include-demo ()
  (div :class "space-y-3"
    (div :class "flex gap-2 items-end"
      (div
        (label :class "block text-xs text-stone-500 mb-1" "Category")
        (select :id "ref-inc-cat" :name "category"
          :class "px-3 py-2 border border-stone-300 rounded text-sm"
          (option :value "all" "All")
          (option :value "books" "Books")
          (option :value "tools" "Tools")))
      (button :sx-get "/reference/api/echo-vals"
        :sx-include "#ref-inc-cat"
        :sx-target "#ref-include-result"
        :sx-swap "innerHTML"
        :class "px-4 py-2 bg-violet-600 text-white rounded text-sm hover:bg-violet-700"
        "Filter"))
    (div :id "ref-include-result"
      :class "p-3 rounded bg-stone-50 text-stone-400 text-sm"
      "Click Filter — the select value is included in the request.")))

;; ---------------------------------------------------------------------------
;; sx-vals
;; ---------------------------------------------------------------------------

(defcomp ~ref-vals-demo ()
  (div :class "space-y-3"
    (button :sx-post "/reference/api/echo-vals"
      :sx-vals "{\"source\": \"demo\", \"page\": \"3\"}"
      :sx-target "#ref-vals-result"
      :sx-swap "innerHTML"
      :class "px-4 py-2 bg-violet-600 text-white rounded text-sm hover:bg-violet-700"
      "Send with extra values")
    (div :id "ref-vals-result"
      :class "p-3 rounded bg-stone-50 text-stone-400 text-sm"
      "Click to see echoed values.")))

;; ---------------------------------------------------------------------------
;; sx-media
;; ---------------------------------------------------------------------------

(defcomp ~ref-media-demo ()
  (div :class "space-y-3"
    (a :href "/reference/attributes/sx-get"
      :sx-get "/reference/attributes/sx-get"
      :sx-target "#main-panel" :sx-select "#main-panel"
      :sx-swap "outerHTML" :sx-push-url "true"
      :sx-media "(min-width: 768px)"
      :class "inline-block px-4 py-2 bg-violet-600 text-white rounded text-sm no-underline hover:bg-violet-700"
      "sx navigation (desktop only)")
    (p :class "text-sm text-stone-500"
      "On screens narrower than 768px this link uses normal navigation. On wider screens it uses sx.")))

;; ---------------------------------------------------------------------------
;; sx-disable
;; ---------------------------------------------------------------------------

(defcomp ~ref-disable-demo ()
  (div :class "space-y-3"
    (div :class "grid grid-cols-2 gap-3"
      (div :class "p-3 border border-stone-200 rounded"
        (p :class "text-xs text-stone-400 mb-2" "sx enabled")
        (button :sx-get "/reference/api/time"
          :sx-target "#ref-dis-a" :sx-swap "innerHTML"
          :class "px-3 py-1 bg-violet-600 text-white rounded text-sm" "Load")
        (div :id "ref-dis-a" :class "mt-2 text-sm text-stone-500" "—"))
      (div :sx-disable "true" :class "p-3 border border-stone-200 rounded"
        (p :class "text-xs text-stone-400 mb-2" "sx disabled")
        (button :sx-get "/reference/api/time"
          :sx-target "#ref-dis-b" :sx-swap "innerHTML"
          :class "px-3 py-1 bg-stone-400 text-white rounded text-sm" "Load")
        (div :id "ref-dis-b" :class "mt-2 text-sm text-stone-500"
          "Button won't fire sx request")))))

;; ---------------------------------------------------------------------------
;; sx-on:*
;; ---------------------------------------------------------------------------

(defcomp ~ref-on-demo ()
  (div :class "space-y-3"
    (button
      :sx-on:click "document.getElementById('ref-on-result').textContent = 'Clicked at ' + new Date().toLocaleTimeString()"
      :class "px-4 py-2 bg-violet-600 text-white rounded text-sm hover:bg-violet-700"
      "Click me")
    (div :id "ref-on-result"
      :class "p-3 rounded bg-stone-50 text-stone-400 text-sm"
      "Click the button — runs JavaScript, no server request.")))

;; ---------------------------------------------------------------------------
;; sx-retry
;; ---------------------------------------------------------------------------

(defcomp ~ref-retry-demo ()
  (div :class "space-y-3"
    (button :sx-get "/reference/api/flaky"
      :sx-target "#ref-retry-result"
      :sx-swap "innerHTML"
      :sx-retry "true"
      :class "px-4 py-2 bg-violet-600 text-white rounded text-sm hover:bg-violet-700"
      "Call flaky endpoint")
    (div :id "ref-retry-result"
      :class "p-3 rounded bg-stone-50 text-stone-400 text-sm"
      "This endpoint fails 2 out of 3 times. sx-retry retries automatically.")))

;; ---------------------------------------------------------------------------
;; data-sx
;; ---------------------------------------------------------------------------

(defcomp ~ref-data-sx-demo ()
  (div :class "space-y-3"
    (div :data-sx "(div :class \"p-3 bg-violet-50 rounded\" (h3 :class \"font-semibold text-violet-800\" \"Client-rendered\") (p :class \"text-sm text-stone-600\" \"This was evaluated in the browser — no server request.\"))")
    (p :class "text-xs text-stone-400" "The content above is rendered client-side from the data-sx attribute.")))

;; ---------------------------------------------------------------------------
;; data-sx-env
;; ---------------------------------------------------------------------------

(defcomp ~ref-data-sx-env-demo ()
  (div :class "space-y-3"
    (div :data-sx "(div :class \"p-3 bg-emerald-50 rounded\" (h3 :class \"font-semibold text-emerald-800\" title) (p :class \"text-sm text-stone-600\" message))"
         :data-sx-env "{\"title\": \"Dynamic content\", \"message\": \"Variables passed via data-sx-env are available in the expression.\"}")
    (p :class "text-xs text-stone-400" "The title and message above come from the data-sx-env JSON.")))

;; ---------------------------------------------------------------------------
;; sx-boost
;; ---------------------------------------------------------------------------

(defcomp ~ref-boost-demo ()
  (div :class "space-y-3"
    (nav :sx-boost "true" :class "flex gap-3"
      (a :href "/reference/attributes/sx-get"
        :class "text-violet-600 hover:text-violet-800 underline text-sm"
        "sx-get")
      (a :href "/reference/attributes/sx-post"
        :class "text-violet-600 hover:text-violet-800 underline text-sm"
        "sx-post")
      (a :href "/reference/attributes/sx-target"
        :class "text-violet-600 hover:text-violet-800 underline text-sm"
        "sx-target"))
    (p :class "text-xs text-stone-400"
      "These links use AJAX navigation via sx-boost — no sx-get needed on each link.")))

;; ---------------------------------------------------------------------------
;; sx-preload
;; ---------------------------------------------------------------------------

(defcomp ~ref-preload-demo ()
  (div :class "space-y-3"
    (button
      :sx-get "/reference/api/time"
      :sx-target "#ref-preload-result"
      :sx-swap "innerHTML"
      :sx-preload "mouseover"
      :class "px-4 py-2 bg-violet-600 text-white rounded hover:bg-violet-700 transition-colors text-sm"
      "Hover then click (preloaded)")
    (div :id "ref-preload-result"
      :class "p-3 rounded bg-stone-50 text-stone-400 text-sm"
      "Hover over the button first, then click — the response is instant.")))

;; ---------------------------------------------------------------------------
;; sx-preserve
;; ---------------------------------------------------------------------------

(defcomp ~ref-preserve-demo ()
  (div :class "space-y-3"
    (div :class "flex gap-2 items-center"
      (button
        :sx-get "/reference/api/time"
        :sx-target "#ref-preserve-container"
        :sx-swap "innerHTML"
        :class "px-4 py-2 bg-violet-600 text-white rounded hover:bg-violet-700 transition-colors text-sm"
        "Swap container")
      (span :class "text-xs text-stone-400" "The input below keeps its value across swaps."))
    (div :id "ref-preserve-container" :class "space-y-2"
      (input :id "ref-preserved-input" :sx-preserve "true"
        :type "text" :placeholder "Type here — preserved across swaps"
        :class "w-full px-3 py-2 border border-stone-300 rounded text-sm")
      (div :class "p-2 bg-stone-50 rounded text-sm text-stone-600"
        "This text will be replaced on swap."))))

;; ---------------------------------------------------------------------------
;; sx-indicator
;; ---------------------------------------------------------------------------

(defcomp ~ref-indicator-demo ()
  (div :class "space-y-3"
    (div :class "flex gap-3 items-center"
      (button
        :sx-get "/reference/api/slow-echo"
        :sx-target "#ref-indicator-result"
        :sx-swap "innerHTML"
        :sx-indicator "#ref-spinner"
        :sx-vals "{\"q\": \"hello\"}"
        :class "px-4 py-2 bg-violet-600 text-white rounded hover:bg-violet-700 transition-colors text-sm"
        "Load (slow)")
      (span :id "ref-spinner"
        :class "text-violet-600 text-sm"
        :style "display: none"
        "Loading..."))
    (div :id "ref-indicator-result"
      :class "p-3 rounded bg-stone-50 text-stone-400 text-sm"
      "Click to load (indicator shows during request).")))

;; ---------------------------------------------------------------------------
;; sx-validate
;; ---------------------------------------------------------------------------

(defcomp ~ref-validate-demo ()
  (div :class "space-y-3"
    (form
      :sx-post "/reference/api/greet"
      :sx-target "#ref-validate-result"
      :sx-swap "innerHTML"
      :sx-validate "true"
      :class "flex gap-2"
      (input :type "email" :name "name" :required "true"
        :placeholder "Enter email (required)"
        :class "flex-1 px-3 py-2 border border-stone-300 rounded text-sm focus:outline-none focus:ring-2 focus:ring-violet-500")
      (button :type "submit"
        :class "px-4 py-2 bg-violet-600 text-white rounded hover:bg-violet-700 transition-colors text-sm"
        "Submit"))
    (div :id "ref-validate-result"
      :class "p-3 rounded bg-stone-50 text-stone-400 text-sm"
      "Submit with invalid/empty email to see validation.")))

;; ---------------------------------------------------------------------------
;; sx-ignore
;; ---------------------------------------------------------------------------

(defcomp ~ref-ignore-demo ()
  (div :class "space-y-3"
    (button
      :sx-get "/reference/api/time"
      :sx-target "#ref-ignore-container"
      :sx-swap "innerHTML"
      :class "px-4 py-2 bg-violet-600 text-white rounded hover:bg-violet-700 transition-colors text-sm"
      "Swap container")
    (div :id "ref-ignore-container" :class "space-y-2"
      (div :sx-ignore "true" :class "p-2 bg-amber-50 rounded border border-amber-200"
        (p :class "text-sm text-amber-800" "This subtree has sx-ignore — it won't change.")
        (input :type "text" :placeholder "Type here — ignored during swap"
          :class "mt-1 w-full px-2 py-1 border border-amber-300 rounded text-sm"))
      (div :class "p-2 bg-stone-50 rounded text-sm text-stone-600"
        "This text WILL be replaced on swap."))))

;; ---------------------------------------------------------------------------
;; sx-optimistic
;; ---------------------------------------------------------------------------

(defcomp ~ref-optimistic-demo ()
  (div :class "space-y-2"
    (div :id "ref-opt-item-1"
      :class "flex items-center justify-between p-2 border border-stone-200 rounded"
      (span :class "text-sm text-stone-700" "Optimistic item A")
      (button :sx-delete "/reference/api/item/opt1"
        :sx-target "#ref-opt-item-1" :sx-swap "delete"
        :sx-optimistic "remove"
        :class "text-red-500 text-sm hover:text-red-700" "Remove"))
    (div :id "ref-opt-item-2"
      :class "flex items-center justify-between p-2 border border-stone-200 rounded"
      (span :class "text-sm text-stone-700" "Optimistic item B")
      (button :sx-delete "/reference/api/item/opt2"
        :sx-target "#ref-opt-item-2" :sx-swap "delete"
        :sx-optimistic "remove"
        :class "text-red-500 text-sm hover:text-red-700" "Remove"))
    (p :class "text-xs text-stone-400"
      "Items fade out immediately on click (optimistic), then are removed when the server responds.")))

;; ---------------------------------------------------------------------------
;; sx-replace-url
;; ---------------------------------------------------------------------------

(defcomp ~ref-replace-url-demo ()
  (div :class "space-y-3"
    (button
      :sx-get "/reference/api/time"
      :sx-target "#ref-replurl-result"
      :sx-swap "innerHTML"
      :sx-replace-url "true"
      :class "px-4 py-2 bg-violet-600 text-white rounded hover:bg-violet-700 transition-colors text-sm"
      "Load (replaces URL)")
    (div :id "ref-replurl-result"
      :class "p-3 rounded bg-stone-50 text-stone-400 text-sm"
      "Click to load — URL changes but no new history entry.")))

;; ---------------------------------------------------------------------------
;; sx-disabled-elt
;; ---------------------------------------------------------------------------

(defcomp ~ref-disabled-elt-demo ()
  (div :class "space-y-3"
    (div :class "flex gap-3 items-center"
      (button :id "ref-diselt-btn"
        :sx-get "/reference/api/slow-echo"
        :sx-target "#ref-diselt-result"
        :sx-swap "innerHTML"
        :sx-disabled-elt "#ref-diselt-btn"
        :sx-vals "{\"q\": \"hello\"}"
        :class "px-4 py-2 bg-violet-600 text-white rounded hover:bg-violet-700 transition-colors text-sm disabled:opacity-50"
        "Click (disables during request)")
      (span :class "text-xs text-stone-400" "Button is disabled while request is in-flight."))
    (div :id "ref-diselt-result"
      :class "p-3 rounded bg-stone-50 text-stone-400 text-sm"
      "Click the button to see it disable during the request.")))

;; ---------------------------------------------------------------------------
;; sx-prompt
;; ---------------------------------------------------------------------------

(defcomp ~ref-prompt-demo ()
  (div :class "space-y-3"
    (button
      :sx-get "/reference/api/prompt-echo"
      :sx-target "#ref-prompt-result"
      :sx-swap "innerHTML"
      :sx-prompt "Enter your name:"
      :class "px-4 py-2 bg-violet-600 text-white rounded hover:bg-violet-700 transition-colors text-sm"
      "Prompt & send")
    (div :id "ref-prompt-result"
      :class "p-3 rounded bg-stone-50 text-stone-400 text-sm"
      "Click to enter a name via prompt — it is sent as the SX-Prompt header.")))

;; ---------------------------------------------------------------------------
;; sx-params
;; ---------------------------------------------------------------------------

(defcomp ~ref-params-demo ()
  (div :class "space-y-3"
    (form
      :sx-post "/reference/api/echo-vals"
      :sx-target "#ref-params-result"
      :sx-swap "innerHTML"
      :sx-params "name"
      :class "flex gap-2"
      (input :type "text" :name "name" :placeholder "Name (sent)"
        :class "flex-1 px-3 py-2 border border-stone-300 rounded text-sm focus:outline-none focus:ring-2 focus:ring-violet-500")
      (input :type "text" :name "secret" :placeholder "Secret (filtered)"
        :class "flex-1 px-3 py-2 border border-stone-300 rounded text-sm focus:outline-none focus:ring-2 focus:ring-violet-500")
      (button :type "submit"
        :class "px-4 py-2 bg-violet-600 text-white rounded hover:bg-violet-700 transition-colors text-sm"
        "Submit"))
    (div :id "ref-params-result"
      :class "p-3 rounded bg-stone-50 text-stone-400 text-sm"
      "Only 'name' will be sent — 'secret' is filtered by sx-params.")))

;; ---------------------------------------------------------------------------
;; sx-sse
;; ---------------------------------------------------------------------------

(defcomp ~ref-sse-demo ()
  (div :class "space-y-3"
    (div :sx-sse "/reference/api/sse-time"
      :sx-sse-swap "time"
      :sx-swap "innerHTML"
      (div :id "ref-sse-result"
        :class "p-3 rounded bg-stone-50 text-stone-600 text-sm font-mono"
        "Connecting to SSE stream..."))
    (p :class "text-xs text-stone-400"
      "Server pushes time updates every 2 seconds via Server-Sent Events.")))
