;; ---------------------------------------------------------------------------
;; L6: App Shell
;; ---------------------------------------------------------------------------
(defcomp ()
  (~docs/page :title "Layer 6: Client-First App Shell"

    (p (~tw :tokens "text-stone-500 text-sm italic mb-8")
      "Skip SSR entirely for canvas-heavy apps. Server returns a minimal HTML shell; "
      "all rendering happens client-side.")

    (~docs/section :title "Live Demo" :id "demo"
      (p "A mini single-page app rendered entirely client-side. Navigation switches views via a " (code "route") " signal — no server round-trips. Counter state persists across view switches because signals live in closures, not the DOM.")
      (~reactive-runtime/demo-app-shell)
      (~docs/code :src (highlight "(defisland ~demo-app-shell ()\n  (let ((route (signal \"home\"))\n        (count (signal 0)))\n    ;; Client-side nav\n    (nav\n      (button :on-click (fn (e) (reset! route \"home\"))\n        :class (str ... (if (= (deref route) \"home\") \"active\" \"inactive\"))\n        \"Home\")\n      ...)\n    ;; Reactive view switching\n    (cond\n      (= (deref route) \"home\")\n        (div (p \"Client-rendered. No server round-trip.\"))\n      (= (deref route) \"counter\")\n        (div (span (deref count)) ...)\n      (= (deref route) \"about\")\n        (div (p \"Entirely client-rendered.\")))))" "lisp"))
      (p "This island IS a mini app shell. The " (code "make-app") " function generalizes the pattern: server returns " (code "<div id=\"sx-app-root\">") " + SX loader, " (code "app-boot") " mounts the entry component, " (code "app-navigate!") " switches routes — all using existing " (code "sx-mount") " and signals."))

    (~docs/section :title "API" :id "app-api"

      (~docs/code :src (highlight
        "(define my-app (make-app\n  {:entry ~drawing-app\n   :stores (list canvas-state tool-state)\n   :routes {\"/\" ~drawing-app\n            \"/gallery\" ~gallery-view}\n   :head (list (link :rel \"stylesheet\" :href \"/static/app.css\"))}))\n\n;; Server: generate minimal HTML shell\n(app-shell-html my-app)\n;; => <!doctype html>...<div id=\"sx-app-root\">...</div>...\n\n;; Client: boot the app into the root element\n(app-boot my-app (dom-query \"#sx-app-root\"))\n\n;; Client: navigate between routes\n(app-navigate! my-app \"/gallery\")"
        "lisp")))

    (~docs/section :title "What the Server Returns" :id "app-shell"

      (~docs/code :src (highlight
        "<!doctype html>\n<html>\n<head>\n  <link rel=\"stylesheet\" href=\"/static/app.css\">\n  <script src=\"/static/scripts/sx-browser.js\"></script>\n</head>\n<body>\n  <div id=\"sx-app-root\"></div>\n  <script>\n    SX.boot(function(sx) {\n      sx.appBoot(/* app config */)\n    })\n  </script>\n</body>\n</html>"
        "html"))

      (p "The shell contains no rendered content — just the mount point and loader. "
         "Uses existing " (code "sx-mount") " and " (code "sx-hydrate-islands") " from boot.sx.")

      (p "~330 lines. Orchestrates all other layers."))))
