(defcomp
  ()
  (~docs/page
    :title "Reactive Islands"
    (~docs/section
      :title "Architecture"
      :id "architecture"
      (p "Two orthogonal bars control how an SX page works:")
      (ul
        (~tw :tokens "space-y-1 text-stone-600 list-disc pl-5")
        (li
          (strong "Render boundary")
          " — where rendering happens (server HTML vs client DOM)")
        (li
          (strong "State flow")
          " — how state flows (server state vs client signals)"))
      (div
        (~tw :tokens "overflow-x-auto mt-4 mb-4")
        (table
          (~tw :tokens "w-full text-sm text-left")
          (thead
            (tr
              (~tw :tokens "border-b border-stone-200")
              (th (~tw :tokens "py-2 px-3 font-semibold text-stone-700") "")
              (th
                (~tw :tokens "py-2 px-3 font-semibold text-stone-700")
                "Server State")
              (th
                (~tw :tokens "py-2 px-3 font-semibold text-stone-700")
                "Client State")))
          (tbody
            (~tw :tokens "text-stone-600")
            (tr
              (~tw :tokens "border-b border-stone-100")
              (td
                (~tw :tokens "py-2 px-3 font-semibold text-stone-700")
                "Server Rendering")
              (td (~tw :tokens "py-2 px-3") "Pure hypermedia (htmx)")
              (td (~tw :tokens "py-2 px-3") "SSR + hydrated islands"))
            (tr
              (~tw :tokens "border-b border-stone-100")
              (td
                (~tw :tokens "py-2 px-3 font-semibold text-stone-700")
                "Client Rendering")
              (td (~tw :tokens "py-2 px-3") "SX wire format (current)")
              (td
                (~tw :tokens "py-2 px-3 font-semibold text-violet-700")
                "Reactive islands (this)")))))
      (p
        "Most content stays pure hypermedia. Interactive regions opt into reactivity. The author controls where each component sits on both bars."))
    (~docs/section
      :title "Four Levels"
      :id "levels"
      (div
        (~tw :tokens "space-y-4")
        (div
          (~tw :tokens "rounded border border-stone-200 p-4")
          (div
            (~tw :tokens "font-semibold text-stone-800")
            "Level 0: Pure Hypermedia")
          (p
            (~tw :tokens "text-sm text-stone-600 mt-1")
            "The default. "
            (code "sx-get")
            ", "
            (code "sx-post")
            ", "
            (code "sx-swap")
            ". Server renders everything. No client state. 90% of a typical application."))
        (div
          (~tw :tokens "rounded border border-stone-200 p-4")
          (div
            (~tw :tokens "font-semibold text-stone-800")
            "Level 1: Local DOM Operations")
          (p
            (~tw :tokens "text-sm text-stone-600 mt-1")
            "Imperative escapes: "
            (code "toggle!")
            ", "
            (code "set-attr!")
            ", "
            (code "on-event")
            ". Micro-interactions too small for a server round-trip."))
        (div
          (~tw :tokens "rounded border border-violet-300 bg-violet-50 p-4")
          (div
            (~tw :tokens "font-semibold text-violet-900")
            "Level 2: Reactive Islands")
          (p
            (~tw :tokens "text-sm text-stone-600 mt-1")
            (code "defisland")
            " components with local signals. Fine-grained DOM updates "
            (em "without")
            " virtual DOM, diffing, or component re-renders. A signal change updates only the DOM nodes that read it."))
        (div
          (~tw :tokens "rounded border border-stone-200 p-4")
          (div
            (~tw :tokens "font-semibold text-stone-800")
            "Level 3: Connected Islands")
          (p
            (~tw :tokens "text-sm text-stone-600 mt-1")
            "Islands that share state via signal props or named stores ("
            (code "def-store")
            " / "
            (code "use-store")
            ")."))))
    (~docs/section
      :title "Signal Primitives"
      :id "signals"
      (~docs/code
        :src (highlight
          "(signal v)      ;; create a reactive container\n(deref s)        ;; read value — subscribes in reactive context\n(reset! s v)     ;; write new value — notifies subscribers\n(swap! s f)      ;; update via function: (f old-value)\n(computed fn)    ;; derived signal — auto-tracks dependencies\n(effect fn)      ;; side effect — re-runs when deps change\n(batch fn)       ;; group writes — one notification pass"
          "lisp"))
      (p
        "Signals are values, not hooks. Create them anywhere — conditionals, loops, closures. No rules of hooks. Pass them as arguments, store them in dicts, share between islands."))
    (~docs/section
      :title "Island Lifecycle"
      :id "lifecycle"
      (ol
        (~tw :tokens "space-y-2 text-stone-600 list-decimal list-inside")
        (li
          (strong "Definition: ")
          (code "defisland")
          " registers a reactive component (like "
          (code "defcomp")
          " + island flag)")
        (li
          (strong "Server render: ")
          "Body evaluated with initial values. "
          (code "deref")
          " returns plain value. Output wrapped in "
          (code "data-sx-island")
          " / "
          (code "data-sx-state"))
        (li
          (strong "Client hydration: ")
          "Finds "
          (code "data-sx-island")
          " elements, creates signals from serialized state, re-renders in reactive context")
        (li
          (strong "Updates: ")
          "Signal changes update only subscribed DOM nodes. No full island re-render")
        (li
          (strong "Disposal: ")
          "Island removed from DOM — all signals and effects cleaned up via "
          (code "with-island-scope"))))
    (~docs/section
      :title "htmx Lakes"
      :id "lakes"
      (p
        "An htmx lake is server-driven content "
        (em "inside")
        " a reactive island. The island provides the reactive boundary; the lake content is swapped via "
        (code "sx-get")
        "/"
        (code "sx-post")
        " like normal hypermedia. This works because signals live in closures, not the DOM.")
      (div
        (~tw :tokens "space-y-2 mt-3")
        (div
          (~tw :tokens "rounded border border-green-200 bg-green-50 p-3")
          (div
            (~tw :tokens "font-semibold text-green-800 text-sm")
            "Swap inside island")
          (p
            (~tw :tokens "text-sm text-stone-600 mt-1")
            "Lake content replaced. Signals survive. Effects rebind to new DOM."))
        (div
          (~tw :tokens "rounded border border-green-200 bg-green-50 p-3")
          (div
            (~tw :tokens "font-semibold text-green-800 text-sm")
            "Swap outside island")
          (p
            (~tw :tokens "text-sm text-stone-600 mt-1")
            "Different part of page updated. Island completely unaffected."))
        (div
          (~tw :tokens "rounded border border-amber-200 bg-amber-50 p-3")
          (div
            (~tw :tokens "font-semibold text-amber-800 text-sm")
            "Swap replaces island")
          (p
            (~tw :tokens "text-sm text-stone-600 mt-1")
            "Island disposed. Local signals lost. Named stores persist — new island reconnects via "
            (code "use-store")
            "."))
        (div
          (~tw :tokens "rounded border border-stone-200 p-3")
          (div
            (~tw :tokens "font-semibold text-stone-800 text-sm")
            "Full page navigation")
          (p
            (~tw :tokens "text-sm text-stone-600 mt-1")
            "Everything cleared. "
            (code "clear-stores")
            " wipes the registry."))))
    (~docs/section
      :title "Event Bridge"
      :id "event-bridge"
      (p
        "A lake has no access to island signals, but can communicate back via DOM custom events. Elements with "
        (code "data-sx-emit")
        " dispatch a "
        (code "CustomEvent")
        " on click; an island effect catches it and updates a signal.")
      (~docs/code
        :src (highlight
          ";; Island listens for events from server-rendered lake content\n(bridge-event container \"cart:add\" items\n  (fn (detail) (append (deref items) detail)))\n\n;; Server-rendered button dispatches CustomEvent on click\n(button :data-sx-emit \"cart:add\"\n        :data-sx-emit-detail (json-serialize (dict :id 42))\n        \"Add to Cart\")"
          "lisp"))
      (p
        "Three primitives: "
        (code "emit-event")
        " (dispatch), "
        (code "on-event")
        " (listen), "
        (code "bridge-event")
        " (listen + update signal with automatic cleanup)."))
    (~docs/section
      :title "Named Stores"
      :id "stores"
      (p
        "A named store is a dict of signals at "
        (em "page")
        " scope — not island scope. Multiple islands share the same signals. Stores survive island destruction and recreation.")
      (~docs/code
        :src (highlight
          ";; Create once — idempotent, returns existing on second call\n(def-store \"cart\" (fn ()\n  (dict :items (signal (list))\n        :count (computed (fn () (length (deref items)))))))\n\n;; Use from any island, anywhere in the DOM\n(let ((store (use-store \"cart\")))\n  (span (deref (get store \"count\"))))"
          "lisp"))
      (p
        (code "def-store")
        " creates, "
        (code "use-store")
        " retrieves, "
        (code "clear-stores")
        " wipes all on full page navigation."))
    (~docs/section
      :title "Examples"
      :id "examples"
      (p "Each example below shows a live island and its source.")
      (~docs/section
        :title "Counter"
        :id "demo-counter"
        (p "Signals, computed, and " (code "swap!") ".")
        (~reactive-islands/index/demo-counter :initial 0)
        (~docs/code
          :src (highlight
            (component-source "~reactive-islands/index/demo-counter")
            "lisp")))
      (~docs/section
        :title "Temperature Converter"
        :id "demo-temperature"
        (p
          "Two signals, each derived from the other via "
          (code "effect")
          ".")
        (~reactive-islands/index/demo-temperature)
        (~docs/code
          :src (highlight
            (component-source "~reactive-islands/index/demo-temperature")
            "lisp")))
      (~docs/section
        :title "Imperative Handlers"
        :id "demo-imperative"
        (p "Multi-statement " (code "(do ...)") " bodies in event handlers.")
        (~reactive-islands/index/demo-imperative)
        (~docs/code
          :src (highlight
            (component-source "~reactive-islands/index/demo-imperative")
            "lisp")))
      (~docs/section
        :title "Stopwatch"
        :id "demo-stopwatch"
        (p
          (code "set-interval")
          " and "
          (code "clear-interval")
          " with signal-driven UI.")
        (~reactive-islands/index/demo-stopwatch)
        (~docs/code
          :src (highlight
            (component-source "~reactive-islands/index/demo-stopwatch")
            "lisp")))
      (~docs/section
        :title "Reactive List"
        :id "demo-reactive-list"
        (p "Dynamic list with keyed reconciliation.")
        (~reactive-islands/index/demo-reactive-list)
        (~docs/code
          :src (highlight
            (component-source "~reactive-islands/index/demo-reactive-list")
            "lisp")))
      (~docs/section
        :title "Input Binding"
        :id "demo-input-binding"
        (p "Two-way binding via " (code ":bind") " attribute.")
        (~reactive-islands/index/demo-input-binding)
        (~docs/code
          :src (highlight
            (component-source "~reactive-islands/index/demo-input-binding")
            "lisp")))
      (~docs/section
        :title "Dynamic Classes"
        :id "demo-dynamic-class"
        (p
          "Reactive class toggling with "
          (code "deref")
          " in attribute expressions.")
        (~reactive-islands/index/demo-dynamic-class)
        (~docs/code
          :src (highlight
            (component-source "~reactive-islands/index/demo-dynamic-class")
            "lisp")))
      (~docs/section
        :title "Portal"
        :id "demo-portal"
        (p "Render content outside the island's DOM subtree.")
        (~reactive-islands/index/demo-portal)
        (~docs/code
          :src (highlight
            (component-source "~reactive-islands/index/demo-portal")
            "lisp")))
      (~docs/section
        :title "Error Boundary"
        :id "demo-error-boundary"
        (p "Catch rendering errors without crashing the page.")
        (~reactive-islands/index/demo-error-boundary)
        (~docs/code
          :src (highlight
            (component-source "~reactive-islands/index/demo-error-boundary")
            "lisp")))
      (~docs/section
        :title "DOM Refs"
        :id "demo-refs"
        (p "Access raw DOM elements via " (code ":ref") " signal.")
        (~reactive-islands/index/demo-refs)
        (~docs/code
          :src (highlight
            (component-source "~reactive-islands/index/demo-refs")
            "lisp")))
      (~docs/section
        :title "Resource"
        :id "demo-resource"
        (p "Async data fetching with loading state.")
        (~reactive-islands/index/demo-resource)
        (~docs/code
          :src (highlight
            (component-source "~reactive-islands/index/demo-resource")
            "lisp")))
      (~docs/section
        :title "Transition"
        :id "demo-transition"
        (p
          "Debounced search with "
          (code "schedule-idle")
          " and "
          (code "batch")
          ".")
        (~reactive-islands/index/demo-transition)
        (~docs/code
          :src (highlight
            (component-source "~reactive-islands/index/demo-transition")
            "lisp")))
      (~docs/section
        :title "Named Stores"
        :id "demo-stores"
        (p
          "Two islands sharing state via "
          (code "def-store")
          " / "
          (code "use-store")
          ".")
        (~reactive-islands/index/demo-store-writer)
        (~docs/code
          :src (highlight
            (component-source "~reactive-islands/index/demo-store-writer")
            "lisp"))
        (~reactive-islands/index/demo-store-reader)
        (~docs/code
          :src (highlight
            (component-source "~reactive-islands/index/demo-store-reader")
            "lisp")))
      (~docs/section
        :title "Event Bridge"
        :id "demo-event-bridge"
        (p
          "Server-rendered content communicating with an island via "
          (code "bridge-event")
          ".")
        (~reactive-islands/index/demo-event-bridge)
        (~docs/code
          :src (highlight
            (component-source "~reactive-islands/index/demo-event-bridge")
            "lisp"))))
    (~docs/section
      :title "Design Principles"
      :id "principles"
      (ol
        (~tw :tokens "space-y-2 text-stone-600 list-decimal list-inside")
        (li
          (strong "Islands are opt-in.")
          " "
          (code "defcomp")
          " is the default. "
          (code "defisland")
          " adds reactivity. No overhead for static content.")
        (li
          (strong "Signals are values, not hooks.")
          " Create anywhere — conditionals, loops, closures. No rules of hooks, no dependency arrays.")
        (li
          (strong "Fine-grained, not component-grained.")
          " A signal change updates the specific DOM node that reads it. No virtual DOM, no diffing, no component re-renders.")
        (li
          (strong "The server is still the authority.")
          " Islands handle client interactions. The server handles auth, data, routing.")
        (li
          (strong "Spec-first.")
          " Signal semantics live in "
          (code "signals.sx")
          ". Bootstrapped to JS and Python. Same primitives on future hosts.")
        (li
          (strong "No build step.")
          " Reactive bindings created at runtime. No JSX compilation, no bundler plugins.")))
    (~docs/section
      :title "Implementation Status"
      :id "status"
      (p
        (~tw :tokens "text-stone-600 mb-3")
        "All signal logic lives in "
        (code ".sx")
        " spec files and is bootstrapped to JavaScript and Python. No SX-specific logic in host languages.")
      (div
        (~tw :tokens "overflow-x-auto rounded border border-stone-200")
        (table
          (~tw :tokens "w-full text-left text-sm")
          (thead
            (tr
              (~tw :tokens "border-b border-stone-200 bg-stone-100")
              (th (~tw :tokens "px-3 py-2 font-medium text-stone-600") "Layer")
              (th (~tw :tokens "px-3 py-2 font-medium text-stone-600") "Status")
              (th (~tw :tokens "px-3 py-2 font-medium text-stone-600") "Files")))
          (tbody
            (tr
              (~tw :tokens "border-b border-stone-100")
              (td (~tw :tokens "px-3 py-2 text-stone-700") "Signal runtime spec")
              (td (~tw :tokens "px-3 py-2 text-green-700 font-medium") "Done")
              (td
                (~tw :tokens "px-3 py-2 font-mono text-xs text-stone-500")
                "signals.sx (291 lines)"))
            (tr
              (~tw :tokens "border-b border-stone-100")
              (td (~tw :tokens "px-3 py-2 text-stone-700") "defisland special form")
              (td (~tw :tokens "px-3 py-2 text-green-700 font-medium") "Done")
              (td
                (~tw :tokens "px-3 py-2 font-mono text-xs text-stone-500")
                "eval.sx, special-forms.sx, render.sx"))
            (tr
              (~tw :tokens "border-b border-stone-100")
              (td
                (~tw :tokens "px-3 py-2 text-stone-700")
                "DOM adapter (reactive rendering)")
              (td (~tw :tokens "px-3 py-2 text-green-700 font-medium") "Done")
              (td
                (~tw :tokens "px-3 py-2 font-mono text-xs text-stone-500")
                "adapter-dom.sx (+140 lines)"))
            (tr
              (~tw :tokens "border-b border-stone-100")
              (td (~tw :tokens "px-3 py-2 text-stone-700") "HTML adapter (SSR)")
              (td (~tw :tokens "px-3 py-2 text-green-700 font-medium") "Done")
              (td
                (~tw :tokens "px-3 py-2 font-mono text-xs text-stone-500")
                "adapter-html.sx (+65 lines)"))
            (tr
              (~tw :tokens "border-b border-stone-100")
              (td (~tw :tokens "px-3 py-2 text-stone-700") "JS bootstrapper")
              (td (~tw :tokens "px-3 py-2 text-green-700 font-medium") "Done")
              (td
                (~tw :tokens "px-3 py-2 font-mono text-xs text-stone-500")
                "bootstrap_js.py, sx-ref.js (4769 lines)"))
            (tr
              (~tw :tokens "border-b border-stone-100")
              (td (~tw :tokens "px-3 py-2 text-stone-700") "Python bootstrapper")
              (td (~tw :tokens "px-3 py-2 text-green-700 font-medium") "Done")
              (td
                (~tw :tokens "px-3 py-2 font-mono text-xs text-stone-500")
                "bootstrap_py.py, sx_ref.py"))
            (tr
              (~tw :tokens "border-b border-stone-100")
              (td (~tw :tokens "px-3 py-2 text-stone-700") "Test suite")
              (td (~tw :tokens "px-3 py-2 text-green-700 font-medium") "17/17")
              (td
                (~tw :tokens "px-3 py-2 font-mono text-xs text-stone-500")
                "test-signals.sx"))
            (tr
              (~tw :tokens "border-b border-stone-100")
              (td (~tw :tokens "px-3 py-2 text-stone-700") "Named stores (L3)")
              (td (~tw :tokens "px-3 py-2 text-green-700 font-medium") "Spec'd")
              (td
                (~tw :tokens "px-3 py-2 font-mono text-xs text-stone-500")
                "signals.sx: def-store, use-store, clear-stores"))
            (tr
              (~tw :tokens "border-b border-stone-100")
              (td (~tw :tokens "px-3 py-2 text-stone-700") "Event bridge")
              (td (~tw :tokens "px-3 py-2 text-green-700 font-medium") "Spec'd")
              (td
                (~tw :tokens "px-3 py-2 font-mono text-xs text-stone-500")
                "signals.sx: emit-event, on-event, bridge-event"))
            (tr
              (~tw :tokens "border-b border-stone-100")
              (td (~tw :tokens "px-3 py-2 text-stone-700") "Client hydration")
              (td (~tw :tokens "px-3 py-2 text-green-700 font-medium") "Spec'd")
              (td
                (~tw :tokens "px-3 py-2 font-mono text-xs text-stone-500")
                "boot.sx: sx-hydrate-islands, hydrate-island, dispose-island"))
            (tr
              (~tw :tokens "border-b border-stone-100")
              (td (~tw :tokens "px-3 py-2 text-stone-700") "Event bindings")
              (td (~tw :tokens "px-3 py-2 text-green-700 font-medium") "Spec'd")
              (td
                (~tw :tokens "px-3 py-2 font-mono text-xs text-stone-500")
                "adapter-dom.sx: :on-click → domListen"))
            (tr
              (~tw :tokens "border-b border-stone-100")
              (td (~tw :tokens "px-3 py-2 text-stone-700") "data-sx-emit processing")
              (td (~tw :tokens "px-3 py-2 text-green-700 font-medium") "Spec'd")
              (td
                (~tw :tokens "px-3 py-2 font-mono text-xs text-stone-500")
                "orchestration.sx: process-emit-elements"))
            (tr
              (~tw :tokens "border-b border-stone-100")
              (td (~tw :tokens "px-3 py-2 text-stone-700") "Island disposal")
              (td (~tw :tokens "px-3 py-2 text-green-700 font-medium") "Done")
              (td
                (~tw :tokens "px-3 py-2 font-mono text-xs text-stone-500")
                "boot.sx, orchestration.sx: dispose-islands-in pre-swap"))
            (tr
              (~tw :tokens "border-b border-stone-100")
              (td (~tw :tokens "px-3 py-2 text-stone-700") "Reactive list")
              (td (~tw :tokens "px-3 py-2 text-green-700 font-medium") "Done")
              (td
                (~tw :tokens "px-3 py-2 font-mono text-xs text-stone-500")
                "adapter-dom.sx: map + deref auto-upgrades"))
            (tr
              (~tw :tokens "border-b border-stone-100")
              (td (~tw :tokens "px-3 py-2 text-stone-700") "Input binding")
              (td (~tw :tokens "px-3 py-2 text-green-700 font-medium") "Done")
              (td
                (~tw :tokens "px-3 py-2 font-mono text-xs text-stone-500")
                "adapter-dom.sx: :bind signal, bind-input"))
            (tr
              (~tw :tokens "border-b border-stone-100")
              (td (~tw :tokens "px-3 py-2 text-stone-700") "Keyed reconciliation")
              (td (~tw :tokens "px-3 py-2 text-green-700 font-medium") "Done")
              (td
                (~tw :tokens "px-3 py-2 font-mono text-xs text-stone-500")
                "adapter-dom.sx: :key attr, extract-key"))
            (tr
              (~tw :tokens "border-b border-stone-100")
              (td (~tw :tokens "px-3 py-2 text-stone-700") "Portals")
              (td (~tw :tokens "px-3 py-2 text-green-700 font-medium") "Done")
              (td
                (~tw :tokens "px-3 py-2 font-mono text-xs text-stone-500")
                "adapter-dom.sx: portal render-dom form"))
            (tr
              (~tw :tokens "border-b border-stone-100")
              (td (~tw :tokens "px-3 py-2 text-stone-700") "Error boundaries")
              (td (~tw :tokens "px-3 py-2 text-green-700 font-medium") "Done")
              (td
                (~tw :tokens "px-3 py-2 font-mono text-xs text-stone-500")
                "adapter-dom.sx: error-boundary render-dom form"))
            (tr
              (~tw :tokens "border-b border-stone-100")
              (td (~tw :tokens "px-3 py-2 text-stone-700") "Resource (async signal)")
              (td (~tw :tokens "px-3 py-2 text-green-700 font-medium") "Done")
              (td
                (~tw :tokens "px-3 py-2 font-mono text-xs text-stone-500")
                "signals.sx: resource, promise-then"))
            (tr
              (~tw :tokens "border-b border-stone-100")
              (td (~tw :tokens "px-3 py-2 text-stone-700") "Suspense pattern")
              (td (~tw :tokens "px-3 py-2 text-green-700 font-medium") "Done")
              (td
                (~tw :tokens "px-3 py-2 font-mono text-xs text-stone-500")
                "resource + cond/deref (no special form)"))
            (tr
              (td (~tw :tokens "px-3 py-2 text-stone-700") "Transition pattern")
              (td (~tw :tokens "px-3 py-2 text-green-700 font-medium") "Done")
              (td
                (~tw :tokens "px-3 py-2 font-mono text-xs text-stone-500")
                "schedule-idle + batch (no special form)"))))))))
