;; ---------------------------------------------------------------------------
;; The Hegelian Synthesis of Hypertext and Reactivity
;; ---------------------------------------------------------------------------

(defcomp ()
  (~docs/page :title "The Hegelian Synthesis"
    (p (~tw :tokens "text-stone-500 text-sm italic mb-8")
      "On the dialectical resolution of the hypertext/reactive contradiction.")
    (~docs/section :title "I. Thesis: The server renders" :id "thesis"
      (p (~tw :tokens "text-stone-600")
        "In the beginning was the hyperlink. The web was born as a system of documents connected by references. A page was a " (em "representation") " — complete, self-contained, delivered whole by the server. The browser was a thin client. It received, it rendered, it followed links. The server was the sole author of state.")
      (p (~tw :tokens "text-stone-600")
        "This is the thesis of the web: " (strong "the server knows") ". It knows what to show. It knows what state you're in. It knows what actions are available. It encodes all of this in the document it sends you. When you click a link, the server sends a new document. When you submit a form, the server processes it and sends another document. The cycle is: request, represent, repeat.")
      (p (~tw :tokens "text-stone-600")
        "Hegel would recognise this as a form of " (em "Substance") " — the server as the unmoved mover, the ground of all content. The client has no interiority. It does not " (em "decide") " anything. It displays what it is told to display. The web page is Spinozistic: a mode of the server, one of its infinite expressions, determined entirely by its cause.")
      (p (~tw :tokens "text-stone-600")
        "htmx is the most faithful modern expression of this thesis. It extends the hyperlink and the form — the two primordial hypermedia controls — to every element and every HTTP verb, but it does not break the paradigm. The server still renders. The server still knows. The server still authors state. htmx simply makes the authoring more fine-grained: instead of replacing the entire page, the server replaces a fragment. The thesis is refined, not rejected.")
      (p (~tw :tokens "text-stone-600")
        "The beauty of the thesis is its simplicity. One source of truth. One rendering pipeline. No synchronisation problems. No stale state. No " (code "useEffect") " cleanup. Every request produces a fresh representation, and the representation " (em "is") " the application. There is nothing hidden behind it, no shadow state, no ghost in the machine.")
      (p (~tw :tokens "text-stone-600")
        "But the thesis has a limit. The server cannot know everything the client experiences. It cannot know that the user's mouse is hovering over a button. It cannot know that a drag is in progress. It cannot know that a counter should increment " (em "now") ", this millisecond, without a round trip. The thesis renders the world from the server's perspective — and the client's perspective, its " (em "Erlebnis") ", its lived experience, is absent."))
    (~docs/section :title "II. Antithesis: The client reacts" :id "antithesis"
      (p (~tw :tokens "text-stone-600")
        "React arrived as the negation of the server-rendered web. Where the thesis said " (em "the server knows") ", React said " (em "the client knows better") ". Where the thesis treated the browser as a display surface, React treated it as an application runtime. Where the thesis sent documents, React sent " (em "programs") ".")
      (p (~tw :tokens "text-stone-600")
        "The Hegelian antithesis is not mere opposition — it is " (em "determinate negation") ". React does not simply reject server rendering. It rejects the specific limitation that the thesis cannot overcome: the absence of immediate, client-local state. React gives the client " (em "interiority") ". The component has state. It has a lifecycle. It makes decisions without consulting the server. It " (em "reacts") ".")
      (p (~tw :tokens "text-stone-600")
        "This is the birth of " (em "Subject") " in the Hegelian sense. The client is no longer pure receptivity. It has " (em "Selbstbewusstsein") " — self-consciousness. It knows its own state. A " (code "useState") " hook is an act of self-positing: the component declares " (em "I have an interior") ". A " (code "useEffect") " is self-reflection: the component observes its own changes and responds. The client becomes, in miniature, a knowing subject.")
      (p (~tw :tokens "text-stone-600")
        "But the antithesis inherits its own contradiction. By giving the client interiority, React creates " (em "two sources of truth") ". The server has its state. The client has its state. They must be synchronised. And synchronisation is the eternal problem of distributed systems — it cannot be solved, only managed. Hence the endless parade of state management libraries, cache invalidation strategies, optimistic updates, revalidation hooks. Each is an attempt to paper over the fundamental contradiction: the client and server both claim to know, and they do not always agree.")
      (p (~tw :tokens "text-stone-600")
        "Worse, the antithesis destroys what the thesis had achieved. The representation is no longer self-contained. A React SPA sends a JavaScript bundle — a program, not a document. The server sends an empty " (code "<div id=\"root\">") " and a prayer. The browser must compile, execute, fetch data, and construct the interface from scratch. The document — the web's primordial unit of meaning — is hollowed out. What arrives is not a representation but an " (em "instruction to construct one") ".")
      (p (~tw :tokens "text-stone-600")
        "Hegel would diagnose this as the antithesis's characteristic failure: it achieves freedom (client autonomy) at the cost of substance (server authority). The SPA is the " (em "beautiful soul") " of web development — pure subjectivity that has cut itself off from the objective world and wonders why everything is so complicated."))
    (~docs/section :title "III. The contradiction in practice" :id "contradiction"
      (p (~tw :tokens "text-stone-600")
        "The practical manifestation of the dialectic is visible in every web team's daily life. The server-rendered camp says: " (em "just use HTML and htmx, it's simpler") ". The React camp says: " (em "you can't build a real app without client state") ". Both are correct. Both are incomplete.")
      (p (~tw :tokens "text-stone-600")
        "The server camp cannot build a colour picker. Cannot build a drag-and-drop interface. Cannot build a spreadsheet. Cannot build anything that requires the client to know its own state between HTTP requests. Every interaction that needs immediacy — every tooltip, every animation, every character-by-character validation — forces the server camp to smuggle in JavaScript through the back door, breaking their own thesis.")
      (p (~tw :tokens "text-stone-600")
        "The React camp cannot deliver a page without JavaScript. Cannot render on first load without a server-rendering framework bolted on top. Cannot cache a representation because there is no stable representation to cache. Cannot inspect a page without devtools because the document is an empty shell. Every improvement — server components, streaming SSR, partial hydration — is an attempt to recover what the thesis already had: server-authored, self-contained documents.")
      (p (~tw :tokens "text-stone-600")
        "The two camps are not in disagreement about different things. They are in disagreement about " (em "the same thing") ": where should state live? The thesis says: on the server. The antithesis says: on the client. Neither can accommodate the obvious truth that " (strong "some state belongs on the server and some belongs on the client") ", and that a coherent architecture must handle both without privileging either."))
    (~docs/section :title "IV. Synthesis: The island in the lake" :id "synthesis"
      (p (~tw :tokens "text-stone-600")
        "Hegel's dialectic does not end in compromise. The synthesis is not half-thesis, half-antithesis. It is a new category that " (em "sublates") " — " (em "aufhebt") " — both: preserving what is true in each while resolving the contradiction between them. The synthesis contains the thesis and antithesis as " (em "moments") " within a higher unity.")
      (p (~tw :tokens "text-stone-600")
        "The island architecture is this synthesis. The " (em "lake") " is the thesis preserved: server-rendered HTML, delivered as complete representations, navigated by hypermedia controls. The " (em "island") " is the antithesis preserved: client-local state, reactive signals, immediate interaction. Neither is primary. Neither is a concession to the other. Both are " (em "moments") " of the same page.")
      (p (~tw :tokens "text-stone-600")
        "But the crucial move — the one that makes this a genuine Hegelian synthesis rather than a mere juxtaposition — is " (strong "the morph") ". When the server sends new content and the client merges it into the existing DOM, hydrated islands are " (em "preserved") ". The server updates the lake. The islands keep their state. The server's new representation flows around the islands like water around rocks. The client's interiority survives the server's authority.")
      (p (~tw :tokens "text-stone-600")
        "This is " (em "Aufhebung") " in its precise meaning: cancellation, preservation, and elevation. The thesis (server authority) is " (em "cancelled") " — the server no longer has total control over the page. It is " (em "preserved") " — the server still renders the document, still determines structure, still delivers representations. It is " (em "elevated") " — the server now renders " (em "around") " reactive islands, acknowledging their autonomy. Simultaneously, the antithesis (client autonomy) is cancelled (the client no longer controls the whole page), preserved (islands keep their state), and elevated (client state now coexists with server-driven updates).")
      (~docs/code :src (highlight ";; The island: reactive state coexists with server lakes.\n;; Lakes are server-morphable slots — the water within the island.\n\n(defisland ~essays/hegelian-synthesis/header ()\n  (let ((families (list \"violet\" \"rose\" \"blue\" \"emerald\"))\n        (idx (signal 0))\n        (current (computed (fn ()\n          (nth families (mod (deref idx) (len families)))))))\n    (a :href \"/\" :sx-get \"/\" :sx-target \"#main-panel\"\n      ;; Lake: server can update the logo\n      (lake :id \"logo\"\n        (span :style (cssx ...) \"(<sx>)\"))\n      ;; Reactive: signal-bound, NOT in a lake\n      (span :style (cssx (:text (colour (deref current) 500)))\n        :on-click (fn (e) (swap! idx inc))\n        \"reactive\")\n      ;; Lake: server can update the copyright\n      (lake :id \"copyright\"\n        (p \"© 2026\")))))\n\n;; Click: colour changes (client state)\n;; Server sends new page — morph enters the island\n;; Lakes update from server content\n;; Reactive span keeps its colour — state survives" "lisp"))
      (p (~tw :tokens "text-stone-600")
        "The " (code "lake") " tag is the key. Inside the island, " (code "(lake :id \"logo\" ...)") " marks a region as server territory — the server can update its content during a morph. The reactive " (code "span") " with its signal-bound style is " (em "not") " in a lake — it is island territory, untouchable by the morph. The morph enters the island, finds the lakes, updates them from the server's new representation, and " (em "flows around") " the reactive nodes like water around rocks.")
      (p (~tw :tokens "text-stone-600")
        "Click the word " (em "reactive") " in the header. The colour changes. Navigate to another page. The morph enters the island, updates the lakes (logo, copyright), but the reactive span — with its colour signal — " (em "persists") ". The client's inner life survives the server's outer renewal."))
    (~docs/section :title "V. Spirit: The self-knowing page" :id "spirit"
      (p (~tw :tokens "text-stone-600")
        "Hegel's system does not end with synthesis. Synthesis becomes a new thesis, which generates its own antithesis, and the dialectic continues. The island architecture is not a final resting place. It is a " (em "moment") " in the self-development of the web.")
      (p (~tw :tokens "text-stone-600")
        "Consider what the synthesis makes possible. The page now has two modes of knowledge: the server's knowledge (what the page should contain) and the client's knowledge (what the user is doing right now). Neither is reducible to the other. Neither is privileged over the other. The page is, in Hegel's terminology, " (em "Spirit") " — " (em "Geist") " — the unity of substance and subject, the place where objective content and subjective experience meet.")
      (p (~tw :tokens "text-stone-600")
        "The self-hosting nature of SX deepens this. The evaluator that renders islands is specified in the same language as the islands themselves (" (code "eval.sx") "). The renderer is specified in the same language (" (code "render.sx") "). The parser is specified in the same language (" (code "parser.sx") "). The system knows itself. It is a specification that specifies its own interpretation. This is Hegel's " (em "absolute knowing") " — not omniscience, but self-transparency. The system is what it knows, and it knows what it is.")
      (p (~tw :tokens "text-stone-600")
        "The morph algorithm is the phenomenological crux. It is the mechanism by which the page achieves continuity of experience through discontinuity of content. The server sends a completely new representation — new HTML, new structure, new text. The morph walks the old and new DOM trees, reconciling them. Where it finds an island — a locus of client subjectivity — it preserves it. Where it finds static content — server substance — it updates it. The result is a page that is simultaneously the same (the island's state persists) and different (the surrounding content has changed).")
      (p (~tw :tokens "text-stone-600")
        "This is Hegel's " (em "identity of identity and difference") ". The page after the morph is the same page (same islands, same signals, same DOM nodes) and a different page (new server content, new navigation state, new URL). The dialectic is not resolved by eliminating one side. It is resolved by maintaining both simultaneously — and the morph is the concrete mechanism that achieves this."))
    (~docs/section :title "VI. The speculative proposition" :id "speculative"
      (p (~tw :tokens "text-stone-600")
        "Hegel distinguished " (em "ordinary") " propositions from " (em "speculative") " ones. An ordinary proposition has a fixed subject and a predicate attached to it from outside: " (em "the rose is red") ". A speculative proposition is one where the predicate reflects back on the subject and transforms it: " (em "the actual is the rational") ".")
      (p (~tw :tokens "text-stone-600")
        "The proposition " (em "React is hypermedia") " is speculative in this sense. It does not mean that React, as it exists, is hypermedia. It means that what React " (em "was trying to be") " — a way to specify interactive UI — is what hypermedia " (em "always already was") " — a way to specify interactive documents. The predicate (hypermedia) transforms the subject (React): once you see that reactive islands are hypermedia controls, you can no longer see React as merely a JavaScript library. It was always an attempt to extend the expressiveness of hypermedia. It just didn't know it.")
      (p (~tw :tokens "text-stone-600")
        "And the converse: " (em "hypermedia is reactive") ". The hyperlink is already a reactive control — it responds to user input (click) by producing a state change (navigation). The form is reactive — it responds to submission by producing a state change (server-side processing + new representation). htmx makes this explicit: any element can react to any event by triggering any HTTP verb. The only thing htmx lacks is " (em "local") " reactivity — the ability to change without consulting the server.")
      (p (~tw :tokens "text-stone-600")
        "Islands supply exactly this. And by doing so, they do not add something foreign to hypermedia. They complete it. They give hypermedia the last degree of freedom it was missing: the ability for a control to react to itself, to maintain its own state, to compute derived values from its own inputs — without breaking the hypermedia contract that the server is the author of the document.")
      (p (~tw :tokens "text-stone-600")
        "The Hegelian synthesis is not a compromise between server rendering and client reactivity. It is the recognition that they were always the same thing seen from different sides. The server renders the document. The document contains controls. Some controls maintain local state. The document flows around them. The state persists through the flow. The server and the client are not two systems bridged together. They are one system that knows itself from two perspectives.")
      (p (~tw :tokens "text-stone-600")
        "Click the word " (em "reactive") " in the header above. The colour changes. The page navigates. The colour survives. That is the Hegelian synthesis of the hypertext/reactive dialectic — not in theory, but in the DOM."))))
