;; Scoped Effects — The Deepest Primitive
;; Algebraic effects as the unified foundation for spreads, islands, lakes, and context.

(defcomp ()
  (~docs/page :title "Scoped Effects — The Deepest Primitive"

    (p (~tw :tokens "text-stone-500 text-sm italic mb-8")
      "Everything SX does — spreads, signals, islands, lakes, morph, context, collect — "
      "is an instance of one pattern: a named scope with a value flowing down, "
      "contributions flowing up, and a propagation mode determining when effects are realised. "
      "This plan traces that pattern to its foundation in algebraic effects "
      "and proposes " (code "scope") " as the single primitive underneath everything.")

    ;; =====================================================================
    ;; I. The Observation
    ;; =====================================================================

    (~docs/section :title "The observation" :id "observation"

      (p "SX has accumulated several mechanisms that all do variations of the same thing:")

      (table (~tw :tokens "w-full text-sm border-collapse mb-6")
        (thead
          (tr (~tw :tokens "border-b border-stone-300")
            (th (~tw :tokens "text-left py-2 pr-4") "Mechanism")
            (th (~tw :tokens "text-left py-2 pr-4") "Direction")
            (th (~tw :tokens "text-left py-2 pr-4") "When")
            (th (~tw :tokens "text-left py-2") "Boundary")))
        (tbody
          (tr (~tw :tokens "border-b border-stone-100")
            (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "spread")
            (td (~tw :tokens "py-2 pr-4") "child → parent")
            (td (~tw :tokens "py-2 pr-4") "render time")
            (td (~tw :tokens "py-2") "element"))
          (tr (~tw :tokens "border-b border-stone-100")
            (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "collect! / collected")
            (td (~tw :tokens "py-2 pr-4") "child → ancestor")
            (td (~tw :tokens "py-2 pr-4") "render time")
            (td (~tw :tokens "py-2") "render tree"))
          (tr (~tw :tokens "border-b border-stone-100")
            (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "provide / context")
            (td (~tw :tokens "py-2 pr-4") "ancestor → child")
            (td (~tw :tokens "py-2 pr-4") "render time")
            (td (~tw :tokens "py-2") "render subtree"))
          (tr (~tw :tokens "border-b border-stone-100")
            (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "signal / effect")
            (td (~tw :tokens "py-2 pr-4") "value → subscribers")
            (td (~tw :tokens "py-2 pr-4") "signal change")
            (td (~tw :tokens "py-2") "reactive scope"))
          (tr (~tw :tokens "border-b border-stone-100")
            (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "defisland")
            (td (~tw :tokens "py-2 pr-4") "server → client")
            (td (~tw :tokens "py-2 pr-4") "hydration")
            (td (~tw :tokens "py-2") "server/client"))
          (tr (~tw :tokens "border-b border-stone-100")
            (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "lake")
            (td (~tw :tokens "py-2 pr-4") "server → client slot")
            (td (~tw :tokens "py-2 pr-4") "navigation/morph")
            (td (~tw :tokens "py-2") "client/server"))
          (tr (~tw :tokens "border-b border-stone-100")
            (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "reactive-spread")
            (td (~tw :tokens "py-2 pr-4") "child → parent")
            (td (~tw :tokens "py-2 pr-4") "signal change")
            (td (~tw :tokens "py-2") "element"))
          (tr
            (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "def-store / use-store")
            (td (~tw :tokens "py-2 pr-4") "island ↔ island")
            (td (~tw :tokens "py-2 pr-4") "signal change")
            (td (~tw :tokens "py-2") "cross-island"))))

      (p "Eight mechanisms. Each invented separately for a real use case. "
         "Each with its own API surface, its own implementation path, its own section in the spec.")

      (p "But look at the table. Every row is: " (em "a named region, "
         "a direction of data flow, a moment when effects are realised, "
         "and a boundary that determines what crosses") ". They are all the same shape."))


    ;; =====================================================================
    ;; II. Three propagation modes
    ;; =====================================================================

    (~docs/section :title "Three propagation modes" :id "propagation"

      (p "The \"when\" column has exactly three values. These are the three "
         "propagation modes of the render tree:")

      (~docs/subsection :title "Render propagation"
        (p "Effects are realised " (strong "during the render pass") ". "
           "Synchronous, one-shot, deterministic. The renderer walks the tree, "
           "encounters effects, handles them immediately.")
        (p "Instances: " (code "provide/context/emit!") ", " (code "spread") ", "
           (code "collect!/collected") ".")
        (p "Characteristic: by the time rendering finishes, all render-time effects "
           "are fully resolved. The output is static HTML with everything baked in."))

      (~docs/subsection :title "Reactive propagation"
        (p "Effects are realised " (strong "when signals change") ". "
           "Fine-grained, incremental, potentially infinite. A signal notifies "
           "its subscribers, each subscriber updates its piece of the DOM.")
        (p "Instances: " (code "signal/effect/computed") ", " (code "reactive-spread") ", "
           (code "defisland") ", " (code "def-store/use-store") ".")
        (p "Characteristic: the initial render produces a snapshot. "
           "Subsequent changes propagate through the signal graph without re-rendering. "
           "Each signal write touches only the DOM nodes that actually depend on it."))

      (~docs/subsection :title "Morph propagation"
        (p "Effects are realised " (strong "when the server sends new HTML") ". "
           "Network-bound, server-initiated, structural. The morph algorithm "
           "compares old and new DOM trees and surgically updates.")
        (p "Instances: " (code "lake") ", full-page morph, " (code "sx-get/sx-post") " responses.")
        (p "Characteristic: the server is the source of truth for content. "
           "The client has reactive state that must be " (em "protected") " during morph. "
           "Lakes mark the boundaries: morph enters islands, finds lake elements by ID, "
           "updates their children, leaves reactive attrs untouched.")))


    ;; =====================================================================
    ;; III. The scope primitive
    ;; =====================================================================

    (~docs/section :title "The scope primitive" :id "scope"

      (p "A " (code "scope") " is a named region of the render tree with three properties:")
      (ol (~tw :tokens "space-y-2 text-stone-600")
        (li (strong "Value") " — data flowing " (em "downward") " to descendants (readable via " (code "context") ")")
        (li (strong "Accumulator") " — data flowing " (em "upward") " from descendants (writable via " (code "emit!") ")")
        (li (strong "Propagation mode") " — " (em "when") " effects on this scope are realised"))

      (~docs/code :src (highlight "(scope \"name\"\n  :value expr           ;; downward (readable by descendants)\n  :propagation :render  ;; :render | :reactive | :morph\n  body...)" "lisp"))

      (p "Every existing mechanism is a scope with a specific configuration:")

      (table (~tw :tokens "w-full text-sm border-collapse mb-6")
        (thead
          (tr (~tw :tokens "border-b border-stone-300")
            (th (~tw :tokens "text-left py-2 pr-4") "Mechanism")
            (th (~tw :tokens "text-left py-2 pr-4") "Scope equivalent")
            (th (~tw :tokens "text-left py-2") "Propagation")))
        (tbody
          (tr (~tw :tokens "border-b border-stone-100")
            (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "provide")
            (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "(scope name :value v body)")
            (td (~tw :tokens "py-2") ":render"))
          (tr (~tw :tokens "border-b border-stone-100")
            (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "defisland")
            (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "(scope name :propagation :reactive body)")
            (td (~tw :tokens "py-2") ":reactive"))
          (tr (~tw :tokens "border-b border-stone-100")
            (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "lake")
            (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "(scope name :propagation :morph body)")
            (td (~tw :tokens "py-2") ":morph"))
          (tr (~tw :tokens "border-b border-stone-100")
            (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "spread")
            (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "(emit! :element-attrs dict)")
            (td (~tw :tokens "py-2") ":render (implicit)"))
          (tr (~tw :tokens "border-b border-stone-100")
            (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "collect!")
            (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "(emit! name value)")
            (td (~tw :tokens "py-2") ":render"))
          (tr
            (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "def-store")
            (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "(scope name :value (signal v) :propagation :reactive)")
            (td (~tw :tokens "py-2") ":reactive (cross-scope)"))))

      (~docs/subsection :title "Scopes compose by nesting"
        (~docs/code :src (highlight ";; An island with a theme context and a morphable lake\n(scope \"my-island\" :propagation :reactive\n  (let ((colour (signal \"violet\")))\n    (scope \"theme\" :value {:primary colour} :propagation :render\n      (div\n        (h1 :style (str \"color:\" (deref (get (context \"theme\") :primary)))\n          \"Themed heading\")\n        (scope \"product-details\" :propagation :morph\n          ;; Server morphs this on navigation\n          ;; Reactive attrs on the h1 are protected\n          (~product-card :id 42))))))" "lisp"))
        (p "Three scopes, three propagation modes, nested naturally. "
           "The reactive scope manages signal lifecycle. "
           "The render scope provides downward context. "
           "The morph scope marks where server content flows in. "
           "Each scope handles its own effects without knowing about the others.")))


    ;; =====================================================================
    ;; IV. The 2×3 matrix
    ;; =====================================================================

    (~docs/section :title "The 2×3 matrix" :id "matrix"

      (p "Direction (up/down) × propagation mode (render/reactive/morph) gives six cells. "
         "Every mechanism in SX occupies one:")

      (table (~tw :tokens "w-full text-sm border-collapse mb-6")
        (thead
          (tr (~tw :tokens "border-b border-stone-300")
            (th (~tw :tokens "text-left py-2 pr-4") "")
            (th (~tw :tokens "text-left py-2 pr-4") "Render-time")
            (th (~tw :tokens "text-left py-2 pr-4") "Reactive")
            (th (~tw :tokens "text-left py-2") "Morph")))
        (tbody
          (tr (~tw :tokens "border-b border-stone-100")
            (td (~tw :tokens "py-2 pr-4 font-semibold") "Down ↓")
            (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "context")
            (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "reactive context")
            (td (~tw :tokens "py-2 font-mono text-xs") "server props"))
          (tr (~tw :tokens "border-b border-stone-100")
            (td (~tw :tokens "py-2 pr-4 font-semibold") "Up ↑")
            (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "emit! / spread")
            (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "reactive-spread")
            (td (~tw :tokens "py-2 font-mono text-xs") "lake contributions"))
          (tr
            (td (~tw :tokens "py-2 pr-4 font-semibold") "Both ↕")
            (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "provide")
            (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "island")
            (td (~tw :tokens "py-2 font-mono text-xs") "full morph"))))

      (p "Some cells are already implemented. Some are new. "
         "The point is that " (code "scope") " fills them all from " (strong "one primitive") ". "
         "You don't need to invent a new mechanism for each cell — you configure the scope.")

      (~docs/subsection :title "The new cell: reactive context"
        (p "The (Down ↓, Reactive) cell — " (strong "reactive context") " — "
           "is the most interesting gap. It's React's Context + signals, but without "
           "the re-render avalanche that makes React Context slow.")
        (~docs/code :src (highlight ";; Reactive context: value is a signal, propagation is reactive\n(scope \"theme\" :value (signal {:primary \"violet\"}) :propagation :reactive\n  ;; Any descendant reads with context + deref\n  ;; Only the specific DOM node that uses the value updates\n  (h1 :style (str \"color:\" (get (deref (context \"theme\")) :primary))\n    \"This h1 updates when the theme signal changes\")\n  ;; Deep nesting doesn't matter — it's O(1) per subscriber\n  (~deeply-nested-component-tree))" "lisp"))
        (p "React re-renders " (em "every") " component that reads a changed context. "
           "SX's reactive context updates " (em "only") " the DOM nodes that " (code "deref") " the signal. "
           "Same API, fundamentally different performance characteristics.")))


    ;; =====================================================================
    ;; V. Algebraic effects
    ;; =====================================================================

    (~docs/section :title "Algebraic effects: the deepest layer" :id "algebraic-effects"

      (p "The scope primitive has a name in programming language theory: "
         (strong "algebraic effects with handlers") ".")

      (~docs/subsection :title "The correspondence"
        (table (~tw :tokens "w-full text-sm border-collapse mb-6")
          (thead
            (tr (~tw :tokens "border-b border-stone-300")
              (th (~tw :tokens "text-left py-2 pr-4") "Algebraic effects")
              (th (~tw :tokens "text-left py-2 pr-4") "SX")
              (th (~tw :tokens "text-left py-2") "What it does")))
          (tbody
            (tr (~tw :tokens "border-b border-stone-100")
              (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "perform effect")
              (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "emit!")
              (td (~tw :tokens "py-2") "Raise an effect upward through the tree"))
            (tr (~tw :tokens "border-b border-stone-100")
              (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "handle effect")
              (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "scope / provide")
              (td (~tw :tokens "py-2") "Catch and interpret the effect"))
            (tr (~tw :tokens "border-b border-stone-100")
              (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "ask")
              (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "context")
              (td (~tw :tokens "py-2") "Read the nearest handler's value"))
            (tr (~tw :tokens "border-b border-stone-100")
              (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "handler nesting")
              (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "scope nesting")
              (td (~tw :tokens "py-2") "Inner handlers shadow outer ones"))
            (tr
              (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "resumption")
              (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "reactive propagation")
              (td (~tw :tokens "py-2") "Handler can re-invoke the continuation"))))

        (p "The last row is the deep one. In algebraic effect theory, a handler can "
           (strong "resume") " the computation that performed the effect — optionally with "
           "a different value. This is exactly what reactive propagation does: when a signal "
           "changes, the effect handler (the island scope) re-invokes the subscribed "
           "continuations (the effect callbacks) with the new value."))

      (~docs/subsection :title "Why this matters"
        (p "Algebraic effects are " (strong "the most general control flow abstraction known") ". "
           "Exceptions, generators, async/await, coroutines, backtracking, and "
           "nondeterminism are all instances of algebraic effects with different handler strategies.")
        (p "SX's three propagation modes are three handler strategies:")
        (ul (~tw :tokens "list-disc pl-5 space-y-2 text-stone-600")
          (li (strong "Render") " = " (em "one-shot") " handler — handle the effect immediately, "
              "don't resume. Like " (code "try/catch") " for rendering.")
          (li (strong "Reactive") " = " (em "multi-shot") " handler — handle the effect, "
              "then re-handle it every time the value changes. Like a generator that yields "
              "whenever a signal fires.")
          (li (strong "Morph") " = " (em "external resumption") " handler — the server decides "
              "when to resume, sending new content over the network. Like an async/await "
              "where the promise is resolved by a different machine.")))

      (~docs/subsection :title "The effect hierarchy"
        (p "Effects form a hierarchy. Lower-level effects are handled by higher-level scopes:")
        (~docs/code :src (highlight ";; Effect hierarchy (innermost handled first)\n;;\n;; spread        → element scope handles (merge attrs)\n;; emit!          → nearest provide handles (accumulate)\n;; signal write   → reactive scope handles (notify subscribers)\n;; morph          → morph scope handles (diff + patch)\n;;\n;; If no handler is found, the effect bubbles up.\n;; Unhandled effects at the root are errors (like uncaught exceptions).\n;;\n;; This is why (emit! \"cssx\" rule) without a provider\n;; should error — there's no handler for the effect." "lisp"))
        (p "The current " (code "collect!") " is a global accumulator — effectively an "
           "implicit top-level handler. Under the scope model, it would be an explicit "
           (code "provide") " in the layout that handles " (code "\"cssx\"") " effects.")))


    ;; =====================================================================
    ;; VI. What scope enables
    ;; =====================================================================

    (~docs/section :title "What scope enables" :id "enables"

      (~docs/subsection :title "1. New propagation modes"
        (p "The three modes (render, reactive, morph) are not hardcoded — they are "
           "handler strategies. New strategies can be added without new primitives:")
        (ul (~tw :tokens "list-disc pl-5 space-y-2 text-stone-600")
          (li (strong ":animation") " — effects realised on requestAnimationFrame, "
              "batched per frame, interruptible by higher-priority updates")
          (li (strong ":idle") " — effects deferred to requestIdleCallback, "
              "used for non-urgent background updates (the transition pattern)")
          (li (strong ":stream") " — effects realised as server-sent events arrive, "
              "for live data (scores, prices, notifications)")
          (li (strong ":worker") " — effects computed in a Web Worker, "
              "results propagated back to the main thread")))

      (~docs/subsection :title "2. Effect composition"
        (p "Because scopes nest, effects compose naturally:")
        (~docs/code :src (highlight ";; Animation scope inside a reactive scope\n(scope \"island\" :propagation :reactive\n  (let ((items (signal large-list)))\n    (scope \"smooth\" :propagation :animation\n      ;; Updates to items are batched per frame\n      ;; The reactive scope tracks deps\n      ;; The animation scope throttles DOM writes\n      (for-each (fn (item)\n        (div (get item \"name\"))) (deref items)))))" "lisp"))
        (p "The reactive scope notifies when " (code "items") " changes. "
           "The animation scope batches the resulting DOM writes to the next frame. "
           "Neither scope knows about the other. They compose by nesting."))

      (~docs/subsection :title "3. Server/client as effect boundary"
        (p "The deepest consequence: the server/client boundary becomes " (em "just another "
           "scope boundary") ". What crosses it is determined by the propagation mode:")
        (~docs/code :src (highlight ";; The server renders this:\n(scope \"page\" :propagation :render\n  (scope \"header\" :propagation :reactive\n    ;; Client takes over — reactive scope\n    (island-body...))\n  (scope \"content\" :propagation :morph\n    ;; Server controls — morphed on navigation\n    (page-content...))\n  (scope \"footer\" :propagation :render\n    ;; Static — rendered once, never changes\n    (footer...)))" "lisp"))
        (p "The renderer walks the tree. When it hits a reactive scope, it serialises "
           "state and emits a hydration marker. When it hits a morph scope, it emits "
           "a lake marker. When it hits a render scope, it just renders. "
           "The three scope types naturally produce the islands-and-lakes architecture — "
           "not as a special case, but as the " (em "only") " case."))

      (~docs/subsection :title "4. Cross-scope communication"
        (p "Named stores (" (code "def-store/use-store") ") are scopes that transcend "
           "the render tree. Two islands sharing a signal is two reactive scopes "
           "referencing the same named scope:")
        (~docs/code :src (highlight ";; Two islands, one shared scope\n(scope \"cart\" :value (signal []) :propagation :reactive :global true\n  ;; Any island can read/write the cart\n  ;; The scope transcends the render tree\n  ;; Signal propagation handles cross-island updates)" "lisp"))
        (p "The " (code ":global") " flag lifts the scope out of the tree hierarchy "
           "into a named registry. " (code "def-store") " is syntax sugar for this.")))


    ;; =====================================================================
    ;; VII. Implementation path
    ;; =====================================================================

    (~docs/section :title "Implementation path" :id "implementation"

      (p "The path from current SX to the scope primitive follows the existing plan "
         "and adds two phases:")

      (~docs/subsection :title "Phase 1: provide/context/emit! ✓"
        (p (strong "Complete. ") "Render-time dynamic scope. Four primitives: "
           (code "provide") " (special form), " (code "context") ", " (code "emit!") ", "
           (code "emitted") ". Platform provides " (code "scope-push!/scope-pop!") ". "
           "Spreads reimplemented on provide/emit!.")
        (p "See "
           (a :href "/sx/(geography.(provide))" (~tw :tokens "text-violet-600 hover:underline") "provide article")
           " and "
           (a :href "/sx/(geography.(spreads))" (~tw :tokens "text-violet-600 hover:underline") "spreads article")
           "."))

      (~docs/subsection :title "Phase 2: scope as the common form ✓"
        (p (strong "Complete. ") (code "scope") " is now the general form. "
           (code "provide") " is sugar for " (code "(scope name :value v body...)") ". "
           (code "collect!") " creates a lazy root scope with deduplication. "
           "All adapters use " (code "scope-push!/scope-pop!") " directly.")
        (p "The unified platform structure:")
        (~docs/code :src (highlight "_scope_stacks = {}  ;; {name: [{value, emitted: [], dedup: bool}]}" "python"))
        (p "See "
           (a :href "/sx/(geography.(scopes))" (~tw :tokens "text-violet-600 hover:underline") "scopes article")
           "."))

      (~docs/subsection :title "Phase 3: effect handlers (future)"
        (p "Make propagation modes extensible. A " (code ":propagation") " value is a "
           "handler function that determines when and how effects are realised:")
        (~docs/code :src (highlight ";; Custom propagation mode\n(define :debounced\n  (fn (emit-fn delay)\n    ;; Returns a handler that debounces effect realisation\n    (let ((timer nil))\n      (fn (effect)\n        (when timer (clear-timeout timer))\n        (set! timer (set-timeout\n          (fn () (emit-fn effect)) delay))))))\n\n;; Use it\n(scope \"search\" :propagation (:debounced 300)\n  ;; Effects in this scope are debounced by 300ms\n  (input :on-input (fn (e)\n    (emit! \"search\" (get-value e)))))" "lisp"))
        (p (strong "Delivers: ") "user-defined propagation modes (animation, debounce, throttle, "
           "worker, stream), effect composition by nesting, "
           "the full algebraic effects model.")))


    ;; =====================================================================
    ;; VIII. What this means for the spec
    ;; =====================================================================

    (~docs/section :title "What this means for the spec" :id "spec"

      (p "The self-hosting spec currently has separate code paths for each mechanism. "
         "Under the scope model, they converge:")

      (table (~tw :tokens "w-full text-sm border-collapse mb-6")
        (thead
          (tr (~tw :tokens "border-b border-stone-300")
            (th (~tw :tokens "text-left py-2 pr-4") "Spec file")
            (th (~tw :tokens "text-left py-2 pr-4") "Current")
            (th (~tw :tokens "text-left py-2") "After scope")))
        (tbody
          (tr (~tw :tokens "border-b border-stone-100")
            (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "eval.sx")
            (td (~tw :tokens "py-2 pr-4") "provide + defisland as separate special forms")
            (td (~tw :tokens "py-2") "scope as one special form, sugar for provide/defisland/lake"))
          (tr (~tw :tokens "border-b border-stone-100")
            (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "adapter-html.sx")
            (td (~tw :tokens "py-2 pr-4") "provide, island, lake as separate dispatch cases")
            (td (~tw :tokens "py-2") "one scope dispatch, mode determines serialisation"))
          (tr (~tw :tokens "border-b border-stone-100")
            (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "adapter-dom.sx")
            (td (~tw :tokens "py-2 pr-4") "render-dom-island, render-dom-lake, reactive-spread")
            (td (~tw :tokens "py-2") "one render-dom-scope, mode determines lifecycle"))
          (tr (~tw :tokens "border-b border-stone-100")
            (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "engine.sx")
            (td (~tw :tokens "py-2 pr-4") "morph-island-children, sync-attrs, data-sx-reactive-attrs")
            (td (~tw :tokens "py-2") "morph-scope (scope boundary determines skip/update)"))
          (tr
            (td (~tw :tokens "py-2 pr-4 font-mono text-xs") "signals.sx")
            (td (~tw :tokens "py-2 pr-4") "standalone signal runtime")
            (td (~tw :tokens "py-2") "unchanged — signals are the value layer, scopes are the structure layer"))))

      (p "Signals remain orthogonal. A scope's " (code ":value") " can be a signal or a plain "
         "value — the scope doesn't care. The propagation mode determines whether the scope "
         "re-runs effects when the value changes, not whether the value " (em "can") " change."))


    ;; =====================================================================
    ;; IX. The deepest thing
    ;; =====================================================================

    (~docs/section :title "The deepest thing" :id "deepest"

      (p "Go deep enough and there is one operation:")

      (blockquote (~tw :tokens "border-l-4 border-violet-300 pl-4 my-6")
        (p (~tw :tokens "text-lg font-semibold text-stone-700")
          "Evaluate this expression in a scope. Handle effects that cross scope boundaries."))

      (p "Rendering is evaluating expressions in a scope where " (code "emit!") " effects "
         "are handled by accumulating HTML. Reactivity is re-evaluating expressions "
         "when signals fire. Morphing is receiving new expressions from the server "
         "and re-evaluating them in existing scopes.")

      (p "Every SX mechanism — every one — is a specific answer to three questions:")
      (ol (~tw :tokens "space-y-2 text-stone-600")
        (li (strong "What scope") " am I in? (element / subtree / island / lake / global)")
        (li (strong "What direction") " does data flow? (down via context, up via emit)")
        (li (strong "When") " are effects realised? (render / signal change / network)"))

      (p (code "scope") " is the primitive that makes all three questions explicit "
         "and composable. It's the last primitive SX needs.")

      (~docs/note
        (p (strong "Status: ") "Phase 1 (" (code "provide/context/emit!") ") and "
           "Phase 2 (" (code "scope") " unification) are complete. "
           "574 tests pass. All four adapters use " (code "scope-push!/scope-pop!") ". "
           (code "collect!") " is backed by lazy scopes with dedup. "
           "Phase 3 (extensible handlers) is the research frontier — "
           "it may turn out that three modes are sufficient, or it may turn out that "
           "user-defined modes unlock something unexpected.")))))
