"""SX docs site s-expression page components."""
from __future__ import annotations

import os

from shared.sx.jinja_bridge import load_sx_dir, watch_sx_dir
from shared.sx.helpers import (
    sx_call, SxExpr, get_asset_url,
)
from content.highlight import highlight

# Load .sx components from sxc/ directory (not sx/ to avoid name collision)
_sxc_dir = os.path.dirname(__file__)
load_sx_dir(_sxc_dir)
watch_sx_dir(_sxc_dir)



def _code(code: str, language: str = "lisp") -> str:
    """Build a ~doc-code component with highlighted content."""
    highlighted = highlight(code, language)
    return f'(~doc-code :code {highlighted})'


def _example_code(code: str, language: str = "lisp") -> str:
    """Build an ~example-source component with highlighted content."""
    highlighted = highlight(code, language)
    return f'(~example-source :code {highlighted})'


def _placeholder(div_id: str) -> str:
    """Empty placeholder that will be filled by OOB swap on interaction."""
    return (f'(div :id "{div_id}"'
            f'  (div :class "bg-stone-50 border border-stone-200 rounded p-4 mt-3"'
            f'    (p :class "text-stone-400 italic text-sm"'
            f'      "Trigger the demo to see the actual content.")))')


def _component_source_text(*names: str) -> str:
    """Get defcomp source text for named components."""
    from shared.sx.jinja_bridge import _COMPONENT_ENV
    from shared.sx.types import Component
    from shared.sx.parser import serialize
    parts = []
    for name in names:
        key = name if name.startswith("~") else f"~{name}"
        val = _COMPONENT_ENV.get(key)
        if isinstance(val, Component):
            param_strs = ["&key"] + list(val.params)
            if val.has_children:
                param_strs.extend(["&rest", "children"])
            params_sx = "(" + " ".join(param_strs) + ")"
            body_sx = serialize(val.body, pretty=True)
            parts.append(f"(defcomp ~{val.name} {params_sx}\n{body_sx})")
    return "\n\n".join(parts)


def _oob_code(target_id: str, text: str) -> str:
    """OOB swap that displays plain code in a styled block."""
    escaped = text.replace('\\', '\\\\').replace('"', '\\"')
    return (f'(div :id "{target_id}" :sx-swap-oob "innerHTML"'
            f'  (div :class "bg-stone-50 border border-stone-200 rounded p-4 mt-3 overflow-x-auto"'
            f'    (pre :class "text-sm whitespace-pre-wrap"'
            f'      (code "{escaped}"))))')


def _clear_components_btn() -> str:
    """Button that clears the client-side component cache (localStorage + in-memory)."""
    js = ("localStorage.removeItem('sx-components-hash');"
          "localStorage.removeItem('sx-components-src');"
          "var e=Sx.getEnv();Object.keys(e).forEach(function(k){if(k.charAt(0)==='~')delete e[k]});"
          "var b=this;b.textContent='Cleared!';setTimeout(function(){b.textContent='Clear component cache'},2000)")
    return (f'(button :onclick "{js}"'
            f' :class "text-xs text-stone-400 hover:text-stone-600 border border-stone-200'
            f' rounded px-2 py-1 transition-colors"'
            f' "Clear component cache")')


def _full_wire_text(sx_src: str, *comp_names: str) -> str:
    """Build the full wire response text showing component defs + CSS note + sx source.

    Only includes component definitions the client doesn't already have,
    matching the real behaviour of sx_response().
    """
    from quart import request
    parts = []
    if comp_names:
        # Check which components the client already has
        loaded_raw = request.headers.get("SX-Components", "")
        loaded = set(loaded_raw.split(",")) if loaded_raw else set()
        missing = [n for n in comp_names
                   if f"~{n}" not in loaded and n not in loaded]
        if missing:
            comp_text = _component_source_text(*missing)
            if comp_text:
                parts.append(f'<script type="text/sx" data-components>\n{comp_text}\n</script>')
    parts.append('<style data-sx-css>/* new CSS rules */</style>')
    # Pretty-print the sx source for readable display
    try:
        from shared.sx.parser import parse as _parse, serialize as _serialize
        parts.append(_serialize(_parse(sx_src), pretty=True))
    except Exception:
        parts.append(sx_src)
    return "\n\n".join(parts)


# ---------------------------------------------------------------------------
# Navigation helpers
# ---------------------------------------------------------------------------

def _nav_items_sx(items: list[tuple[str, str]], current: str | None = None) -> str:
    """Build nav link items as sx."""
    parts = []
    for label, href in items:
        parts.append(sx_call("nav-link",
            href=href, label=label,
            is_selected="true" if current == label else None,
            select_colours="aria-selected:bg-violet-200 aria-selected:text-violet-900",
        ))
    return "(<> " + " ".join(parts) + ")"


def _sx_header_sx(nav: str | None = None, *, child: str | None = None) -> str:
    """Build the sx docs menu-row."""
    return sx_call("menu-row-sx",
        id="sx-row", level=1, colour="violet",
        link_href="/", link_label="sx",
        link_label_content=SxExpr('(span :class "font-mono" "(</>) sx")'),
        nav=SxExpr(nav) if nav else None,
        child_id="sx-header-child",
        child=SxExpr(child) if child else None,
    )


def _docs_nav_sx(current: str | None = None) -> str:
    from content.pages import DOCS_NAV
    return _nav_items_sx(DOCS_NAV, current)


def _reference_nav_sx(current: str | None = None) -> str:
    from content.pages import REFERENCE_NAV
    return _nav_items_sx(REFERENCE_NAV, current)


def _protocols_nav_sx(current: str | None = None) -> str:
    from content.pages import PROTOCOLS_NAV
    return _nav_items_sx(PROTOCOLS_NAV, current)


def _examples_nav_sx(current: str | None = None) -> str:
    from content.pages import EXAMPLES_NAV
    return _nav_items_sx(EXAMPLES_NAV, current)


def _essays_nav_sx(current: str | None = None) -> str:
    from content.pages import ESSAYS_NAV
    return _nav_items_sx(ESSAYS_NAV, current)


def _main_nav_sx(current_section: str | None = None) -> str:
    from content.pages import MAIN_NAV
    return _nav_items_sx(MAIN_NAV, current_section)


def _sub_row_sx(sub_label: str, sub_href: str, sub_nav: str,
                selected: str = "") -> str:
    """Build the level-2 sub-section menu-row."""
    return sx_call("menu-row-sx",
        id="sx-sub-row", level=2, colour="violet",
        link_href=sub_href, link_label=sub_label,
        selected=selected or None,
        nav=SxExpr(sub_nav),
    )



# ---------------------------------------------------------------------------
# Content builders — return sx source strings
# ---------------------------------------------------------------------------

def _doc_nav_sx(items: list[tuple[str, str]], current: str) -> str:
    """Build the in-page doc navigation pills."""
    items_sx = " ".join(
        f'(list "{label}" "{href}")'
        for label, href in items
    )
    return sx_call("doc-nav", items=SxExpr(f"(list {items_sx})"), current=current)


def _attr_table_sx(title: str, attrs: list[tuple[str, str, bool]]) -> str:
    """Build an attribute reference table."""
    from content.pages import ATTR_DETAILS
    rows = []
    for attr, desc, exists in attrs:
        href = f"/reference/attributes/{attr}" if exists and attr in ATTR_DETAILS else None
        rows.append(sx_call("doc-attr-row", attr=attr, description=desc,
                           exists="true" if exists else None,
                           href=href))
    return (
        f'(div :class "space-y-3"'
        f' (h3 :class "text-xl font-semibold text-stone-700" "{title}")'
        f' (div :class "overflow-x-auto rounded border border-stone-200"'
        f'   (table :class "w-full text-left text-sm"'
        f'     (thead (tr :class "border-b border-stone-200 bg-stone-50"'
        f'       (th :class "px-3 py-2 font-medium text-stone-600" "Attribute")'
        f'       (th :class "px-3 py-2 font-medium text-stone-600" "Description")'
        f'       (th :class "px-3 py-2 font-medium text-stone-600 text-center w-20" "In sx?")))'
        f'     (tbody {" ".join(rows)}))))'
    )


def _primitives_section_sx() -> str:
    """Build the primitives section."""
    from content.pages import PRIMITIVES
    parts = []
    for category, prims in PRIMITIVES.items():
        prims_sx = " ".join(f'"{p}"' for p in prims)
        parts.append(sx_call("doc-primitives-table",
            category=category,
            primitives=SxExpr(f"(list {prims_sx})")))
    return " ".join(parts)


def _headers_table_sx(title: str, headers: list[tuple[str, str, str]]) -> str:
    """Build a headers reference table."""
    rows = []
    for name, value, desc in headers:
        rows.append(
            f'(tr :class "border-b border-stone-100"'
            f' (td :class "px-3 py-2 font-mono text-sm text-violet-700 whitespace-nowrap" "{name}")'
            f' (td :class "px-3 py-2 font-mono text-sm text-stone-500" "{value}")'
            f' (td :class "px-3 py-2 text-stone-700 text-sm" "{desc}"))'
        )
    return (
        f'(div :class "space-y-3"'
        f' (h3 :class "text-xl font-semibold text-stone-700" "{title}")'
        f' (div :class "overflow-x-auto rounded border border-stone-200"'
        f'   (table :class "w-full text-left text-sm"'
        f'     (thead (tr :class "border-b border-stone-200 bg-stone-50"'
        f'       (th :class "px-3 py-2 font-medium text-stone-600" "Header")'
        f'       (th :class "px-3 py-2 font-medium text-stone-600" "Value")'
        f'       (th :class "px-3 py-2 font-medium text-stone-600" "Description")))'
        f'     (tbody {" ".join(rows)}))))'
    )



def _docs_content_sx(slug: str) -> str:
    """Route to the right docs content builder."""
    builders = {
        "introduction": _docs_introduction_sx,
        "getting-started": _docs_getting_started_sx,
        "components": _docs_components_sx,
        "evaluator": _docs_evaluator_sx,
        "primitives": _docs_primitives_sx,
        "css": _docs_css_sx,
        "server-rendering": _docs_server_rendering_sx,
    }
    builder = builders.get(slug, _docs_introduction_sx)
    return builder()


def _docs_introduction_sx() -> str:
    return (
        '(~doc-page :title "Introduction"'
        '  (~doc-section :title "What is sx?" :id "what"'
        '    (p :class "text-stone-600"'
        '      "sx is an s-expression language for building web UIs. '
        'It combines htmx\'s server-first hypermedia approach with React\'s component model. '
        'The server sends s-expression source code over the wire. The client parses, evaluates, and renders it to DOM.")'
        '    (p :class "text-stone-600"'
        '      "The same evaluator runs on both server (Python) and client (JavaScript). '
        'Components defined once render identically in both environments."))'
        '  (~doc-section :title "Design decisions" :id "design"'
        '    (p :class "text-stone-600"'
        '      "HTML elements are first-class: (div :class \\"card\\" (p \\"hello\\")) renders exactly what you\'d expect. '
        'Components use defcomp with keyword parameters and optional children. '
        'The evaluator supports let bindings, conditionals, lambda, map/filter/reduce, and ~80 primitives.")'
        '    (p :class "text-stone-600"'
        '      "sx is not trying to replace JavaScript. It\'s trying to replace the pattern of '
        'shipping a JS framework + build step + client-side router + state management library '
        'just to render some server data into HTML."))'
        '  (~doc-section :title "What sx is not" :id "not"'
        '    (ul :class "space-y-2 text-stone-600"'
        '      (li "Not a general-purpose programming language — it\'s a UI rendering language")'
        '      (li "Not a Lisp implementation — no macros, no continuations, no tail-call optimization")'
        '      (li "Not a replacement for JavaScript — it handles rendering, not arbitrary DOM manipulation")'
        '      (li "Not production-hardened at scale — it runs one website"))))'
    )


def _docs_getting_started_sx() -> str:
    c1 = _code('(div :class "p-4 bg-white rounded"\n  (h1 :class "text-2xl font-bold" "Hello, world!")\n  (p "This is rendered from an s-expression."))')
    c2 = _code('(button\n  :sx-get "/api/data"\n  :sx-target "#result"\n  :sx-swap "innerHTML"\n  "Load data")')
    return (
        f'(~doc-page :title "Getting Started"'
        f'  (~doc-section :title "Minimal example" :id "minimal"'
        f'    (p :class "text-stone-600"'
        f'      "An sx response is s-expression source code with content type text/sx:")'
        f'    {c1}'
        f'    (p :class "text-stone-600"'
        f'      "Add sx-get to any element to make it fetch and render sx:"))'
        f'  (~doc-section :title "Hypermedia attributes" :id "attrs"'
        f'    (p :class "text-stone-600"'
        f'      "Like htmx, sx adds attributes to HTML elements to trigger HTTP requests:")'
        f'    {c2}'
        f'    (p :class "text-stone-600"'
        f'      "sx-get, sx-post, sx-put, sx-delete, sx-patch — all work the same way. '
        f'The response is parsed as sx and rendered into the target element.")))'
    )


def _docs_components_sx() -> str:
    c1 = _code('(defcomp ~card (&key title subtitle &rest children)\n'
               '  (div :class "border rounded p-4"\n'
               '    (h2 :class "font-bold" title)\n'
               '    (when subtitle (p :class "text-stone-500" subtitle))\n'
               '    (div :class "mt-3" children)))')
    c2 = _code('(~card :title "My Card" :subtitle "A description"\n'
               '  (p "First child")\n'
               '  (p "Second child"))')
    return (
        f'(~doc-page :title "Components"'
        f'  (~doc-section :title "defcomp" :id "defcomp"'
        f'    (p :class "text-stone-600"'
        f'      "Components are defined with defcomp. They take keyword parameters and optional children:")'
        f'    {c1}'
        f'    (p :class "text-stone-600"'
        f'      "Use components with the ~ prefix:")'
        f'    {c2})'
        f'  (~doc-section :title "Component caching" :id "caching"'
        f'    (p :class "text-stone-600"'
        f'      "Component definitions are sent in a <script type=\\"text/sx\\" data-components> block. '
        f'The client caches them in localStorage keyed by a content hash. '
        f'On subsequent page loads, the client sends an SX-Components header listing what it has. '
        f'The server only sends definitions the client is missing.")'
        f'    (p :class "text-stone-600"'
        f'      "This means the first page load sends all component definitions (~5-15KB). '
        f'Subsequent navigations send zero component bytes — just the page content."))'
        f'  (~doc-section :title "Parameters" :id "params"'
        f'    (p :class "text-stone-600"'
        f'      "&key declares keyword parameters. &rest children captures remaining positional arguments. '
        f'Missing parameters evaluate to nil. Components always receive all declared parameters — '
        f'use (when param ...) or (if param ... ...) to handle optional values.")))'
    )


def _docs_evaluator_sx() -> str:
    c1 = _code(';; Conditionals\n'
               '(if condition then-expr else-expr)\n'
               '(when condition body...)\n'
               '(cond (test1 body1) (test2 body2) (else default))\n\n'
               ';; Bindings\n'
               '(let ((name value) (name2 value2)) body...)\n'
               '(define name value)\n\n'
               ';; Functions\n'
               '(lambda (x y) (+ x y))\n'
               '(fn (x) (* x x))\n\n'
               ';; Sequencing\n'
               '(do expr1 expr2 expr3)\n'
               '(begin expr1 expr2)\n\n'
               ';; Threading\n'
               '(-> value (fn1 arg) (fn2 arg))')
    c2 = _code('(map (fn (x) (* x 2)) (list 1 2 3))        ;; => (2 4 6)\n'
               '(filter (fn (x) (> x 2)) (list 1 2 3 4 5))  ;; => (3 4 5)\n'
               '(reduce (fn (acc x) (+ acc x)) 0 (list 1 2 3)) ;; => 6\n'
               '(some (fn (x) (> x 3)) (list 1 2 3 4))      ;; => true\n'
               '(every? (fn (x) (> x 0)) (list 1 2 3))      ;; => true')
    return (
        f'(~doc-page :title "Evaluator"'
        f'  (~doc-section :title "Special forms" :id "special"'
        f'    (p :class "text-stone-600"'
        f'      "Special forms have lazy evaluation — arguments are not evaluated before the form runs:")'
        f'    {c1})'
        f'  (~doc-section :title "Higher-order forms" :id "higher"'
        f'    (p :class "text-stone-600"'
        f'      "These operate on collections with function arguments:")'
        f'    {c2}))'
    )


def _docs_primitives_sx() -> str:
    prims = _primitives_section_sx()
    return (
        f'(~doc-page :title "Primitives"'
        f'  (~doc-section :title "Built-in functions" :id "builtins"'
        f'    (p :class "text-stone-600"'
        f'      "sx provides ~80 built-in pure functions. '
        f'They work identically on server (Python) and client (JavaScript).")'
        f'    (div :class "space-y-6" {prims})))'
    )


def _docs_css_sx() -> str:
    c1 = _code('# First page load:\n'
               'GET / HTTP/1.1\n\n'
               'HTTP/1.1 200 OK\n'
               'Content-Type: text/html\n'
               '# Full CSS in <style id="sx-css"> + hash in <meta name="sx-css-classes">\n\n'
               '# Subsequent navigation:\n'
               'GET /about HTTP/1.1\n'
               'SX-Css: a1b2c3d4\n\n'
               'HTTP/1.1 200 OK\n'
               'Content-Type: text/sx\n'
               'SX-Css-Hash: e5f6g7h8\n'
               'SX-Css-Add: bg-blue-500,text-white,rounded-lg\n'
               '# Only new rules in <style data-sx-css>', "bash")
    return (
        f'(~doc-page :title "On-Demand CSS"'
        f'  (~doc-section :title "How it works" :id "how"'
        f'    (p :class "text-stone-600"'
        f'      "sx scans every response for CSS class names used in :class attributes. '
        f'It looks up only those classes in a pre-parsed Tailwind CSS registry and ships '
        f'just the rules that are needed. No build step. No purging. No unused CSS.")'
        f'    (p :class "text-stone-600"'
        f'      "On the first page load, the full set of used classes is embedded in a <style> block. '
        f'A hash of the class set is stored. On subsequent navigations, the client sends the hash '
        f'in the SX-Css header. The server computes the diff and sends only new rules via '
        f'SX-Css-Add and a <style data-sx-css> block."))'
        f'  (~doc-section :title "The protocol" :id "protocol"'
        f'    {c1})'
        f'  (~doc-section :title "Advantages" :id "advantages"'
        f'    (ul :class "space-y-2 text-stone-600"'
        f'      (li "Zero build step — no Tailwind CLI, no PostCSS, no purging")'
        f'      (li "Exact CSS — never ships a rule that isn\'t used on the page")'
        f'      (li "Incremental — subsequent navigations only ship new rules")'
        f'      (li "Component-aware — pre-scans component definitions at registration time")))'
        f'  (~doc-section :title "Disadvantages" :id "disadvantages"'
        f'    (ul :class "space-y-2 text-stone-600"'
        f'      (li "Requires the full Tailwind CSS file loaded in memory at startup (~4MB parsed)")'
        f'      (li "Regex-based class scanning — can miss dynamically constructed class names")'
        f'      (li "No @apply support — classes must be used directly")'
        f'      (li "Tied to Tailwind\'s utility class naming conventions"))))'
    )


def _docs_server_rendering_sx() -> str:
    c1 = _code('from shared.sx.helpers import sx_page, sx_response, sx_call\n'
               'from shared.sx.parser import SxExpr\n\n'
               '# Build a component call from Python kwargs\n'
               'sx_call("card", title="Hello", subtitle="World")\n\n'
               '# Return an sx wire-format response\n'
               'return sx_response(sx_call("card", title="Hello"))\n\n'
               '# Return a full HTML page shell with sx boot\n'
               'return sx_page(ctx, page_sx)', "python")
    return (
        f'(~doc-page :title "Server Rendering"'
        f'  (~doc-section :title "Python API" :id "python"'
        f'    (p :class "text-stone-600"'
        f'      "The server-side sx library provides several entry points for rendering:")'
        f'    {c1})'
        f'  (~doc-section :title "sx_call" :id "sx-call"'
        f'    (p :class "text-stone-600"'
        f'      "sx_call converts Python kwargs to an s-expression component call. '
        f'Snake_case becomes kebab-case. SxExpr values are inlined without quoting. '
        f'None becomes nil. Bools become true/false."))'
        f'  (~doc-section :title "sx_response" :id "sx-response"'
        f'    (p :class "text-stone-600"'
        f'      "sx_response returns a Quart Response with content type text/sx. '
        f'It prepends missing component definitions, scans for CSS classes, '
        f'and sets SX-Css-Hash and SX-Css-Add headers."))'
        f'  (~doc-section :title "sx_page" :id "sx-page"'
        f'    (p :class "text-stone-600"'
        f'      "sx_page returns a minimal HTML document that boots the page from sx source. '
        f'The browser loads component definitions and page sx from inline <script> tags, '
        f'then sx.js renders everything client-side. CSS rules are pre-scanned and injected.")))'
    )


# ---------------------------------------------------------------------------
# Reference pages
# ---------------------------------------------------------------------------

def _reference_content_sx(slug: str) -> str:
    builders = {
        "attributes": _reference_attrs_sx,
        "headers": _reference_headers_sx,
        "events": _reference_events_sx,
        "js-api": _reference_js_api_sx,
    }
    return builders.get(slug or "", _reference_attrs_sx)()


def _reference_index_sx() -> str:
    """Build the reference index page with links to sub-sections."""
    sections = [
        ("Attributes", "/reference/attributes",
         "All sx attributes — request verbs, behavior modifiers, and sx-unique features."),
        ("Headers", "/reference/headers",
         "Custom HTTP headers used to coordinate between the sx client and server."),
        ("Events", "/reference/events",
         "DOM events fired during the sx request lifecycle."),
        ("JS API", "/reference/js-api",
         "JavaScript functions for parsing, evaluating, and rendering s-expressions."),
    ]
    cards = []
    for label, href, desc in sections:
        cards.append(
            f'(a :href "{href}"'
            f'  :sx-get "{href}" :sx-target "#main-panel" :sx-select "#main-panel"'
            f'  :sx-swap "outerHTML" :sx-push-url "true"'
            f'  :class "block p-5 rounded-lg border border-stone-200 hover:border-violet-300'
            f' hover:shadow-sm transition-all no-underline"'
            f'  (h3 :class "text-lg font-semibold text-violet-700 mb-1" "{label}")'
            f'  (p :class "text-stone-600 text-sm" "{desc}"))'
        )
    return (
        f'(~doc-page :title "Reference"'
        f'  (p :class "text-stone-600 mb-6"'
        f'    "Complete reference for the sx client library.")'
        f'  (div :class "grid gap-4 sm:grid-cols-2"'
        f'    {" ".join(cards)}))'
    )


def _reference_attr_detail_sx(slug: str) -> str:
    """Build a detail page for a single sx attribute."""
    from content.pages import ATTR_DETAILS
    detail = ATTR_DETAILS.get(slug)
    if not detail:
        return (
            f'(~doc-page :title "Not Found"'
            f'  (p :class "text-stone-600"'
            f'    "No documentation found for \\"{slug}\\"."))'
        )

    title = slug
    desc = detail["description"]
    escaped_desc = desc.replace('\\', '\\\\').replace('"', '\\"')

    # Live demo
    demo_name = detail.get("demo")
    demo_sx = ""
    if demo_name:
        demo_sx = (
            f'  (~example-card :title "Demo"'
            f'    (~example-demo (~{demo_name})))'
        )

    # S-expression source
    example_sx = _example_code(detail["example"], "lisp")

    # Server handler (s-expression)
    handler_sx = ""
    if "handler" in detail:
        handler_sx = (
            f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6"'
            f'    "Server handler")'
            f'  {_example_code(detail["handler"], "lisp")}'
        )

    # Wire response placeholder (only for attrs with server interaction)
    wire_sx = ""
    if "handler" in detail:
        wire_id = slug.replace(":", "-").replace("*", "star")
        wire_sx = (
            f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6"'
            f'    "Wire response")'
            f'  (p :class "text-stone-500 text-sm mb-2"'
            f'    "Trigger the demo to see the raw response the server sends.")'
            f'  {_placeholder("ref-wire-" + wire_id)}'
        )

    return (
        f'(~doc-page :title "{title}"'
        f'  (p :class "text-stone-600 mb-6" "{escaped_desc}")'
        f'  {demo_sx}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6"'
        f'    "S-expression")'
        f'  {example_sx}'
        f'  {handler_sx}'
        f'  {wire_sx})'
    )


def _reference_attrs_sx() -> str:
    from content.pages import REQUEST_ATTRS, BEHAVIOR_ATTRS, SX_UNIQUE_ATTRS, HTMX_MISSING_ATTRS
    return (
        f'(~doc-page :title "Attribute Reference"'
        f'  (p :class "text-stone-600 mb-6"'
        f'    "sx attributes mirror htmx where possible. This table shows what exists, '
        f'what\'s unique to sx, and what\'s not yet implemented.")'
        f'  (div :class "space-y-8"'
        f'    {_attr_table_sx("Request Attributes", REQUEST_ATTRS)}'
        f'    {_attr_table_sx("Behavior Attributes", BEHAVIOR_ATTRS)}'
        f'    {_attr_table_sx("Unique to sx", SX_UNIQUE_ATTRS)}'
        f'    {_attr_table_sx("htmx features not yet in sx", HTMX_MISSING_ATTRS)}))'
    )


def _reference_headers_sx() -> str:
    from content.pages import REQUEST_HEADERS, RESPONSE_HEADERS
    return (
        f'(~doc-page :title "Headers"'
        f'  (p :class "text-stone-600 mb-6"'
        f'    "sx uses custom HTTP headers to coordinate between client and server.")'
        f'  (div :class "space-y-8"'
        f'    {_headers_table_sx("Request Headers", REQUEST_HEADERS)}'
        f'    {_headers_table_sx("Response Headers", RESPONSE_HEADERS)}))'
    )


def _reference_events_sx() -> str:
    from content.pages import EVENTS
    rows = []
    for name, desc in EVENTS:
        rows.append(
            f'(tr :class "border-b border-stone-100"'
            f' (td :class "px-3 py-2 font-mono text-sm text-violet-700 whitespace-nowrap" "{name}")'
            f' (td :class "px-3 py-2 text-stone-700 text-sm" "{desc}"))'
        )
    return (
        f'(~doc-page :title "Events"'
        f'  (p :class "text-stone-600 mb-6"'
        f'    "sx fires custom DOM events at various points in the request lifecycle.")'
        f'  (div :class "overflow-x-auto rounded border border-stone-200"'
        f'    (table :class "w-full text-left text-sm"'
        f'      (thead (tr :class "border-b border-stone-200 bg-stone-50"'
        f'        (th :class "px-3 py-2 font-medium text-stone-600" "Event")'
        f'        (th :class "px-3 py-2 font-medium text-stone-600" "Description")))'
        f'      (tbody {" ".join(rows)}))))'
    )


def _reference_js_api_sx() -> str:
    from content.pages import JS_API
    rows = []
    for name, desc in JS_API:
        rows.append(
            f'(tr :class "border-b border-stone-100"'
            f' (td :class "px-3 py-2 font-mono text-sm text-violet-700 whitespace-nowrap" "{name}")'
            f' (td :class "px-3 py-2 text-stone-700 text-sm" "{desc}"))'
        )
    return (
        f'(~doc-page :title "JavaScript API"'
        f'  (p :class "text-stone-600 mb-6"'
        f'    "The client-side sx.js library exposes a public API for programmatic use.")'
        f'  (div :class "overflow-x-auto rounded border border-stone-200"'
        f'    (table :class "w-full text-left text-sm"'
        f'      (thead (tr :class "border-b border-stone-200 bg-stone-50"'
        f'        (th :class "px-3 py-2 font-medium text-stone-600" "Method")'
        f'        (th :class "px-3 py-2 font-medium text-stone-600" "Description")))'
        f'      (tbody {" ".join(rows)}))))'
    )


# ---------------------------------------------------------------------------
# Protocol pages
# ---------------------------------------------------------------------------

def _protocol_content_sx(slug: str) -> str:
    builders = {
        "wire-format": _protocol_wire_format_sx,
        "fragments": _protocol_fragments_sx,
        "resolver-io": _protocol_resolver_io_sx,
        "internal-services": _protocol_internal_services_sx,
        "activitypub": _protocol_activitypub_sx,
        "future": _protocol_future_sx,
    }
    return builders.get(slug, _protocol_wire_format_sx)()


def _protocol_wire_format_sx() -> str:
    c1 = _code('HTTP/1.1 200 OK\n'
               'Content-Type: text/sx\n'
               'SX-Css-Hash: a1b2c3d4\n\n'
               '(div :class "p-4"\n'
               '  (~card :title "Hello"))', "bash")
    return (
        f'(~doc-page :title "Wire Format"'
        f'  (~doc-section :title "The text/sx content type" :id "content-type"'
        f'    (p :class "text-stone-600"'
        f'      "sx responses use content type text/sx. The body is s-expression source code. '
        f'The client parses and evaluates it, then renders the result into the DOM.")'
        f'    {c1})'
        '  (~doc-section :title "Request lifecycle" :id "lifecycle"'
        '    (p :class "text-stone-600"'
        '      "1. User interacts with an element that has sx-get/sx-post/etc.")'
        '    (p :class "text-stone-600"'
        '      "2. sx.js fires sx:beforeRequest, then sends the HTTP request with SX-Request: true header.")'
        '    (p :class "text-stone-600"'
        '      "3. Server builds s-expression tree, scans CSS classes, prepends missing component definitions.")'
        '    (p :class "text-stone-600"'
        '      "4. Client receives text/sx response, parses it, evaluates it, renders to DOM.")'
        '    (p :class "text-stone-600"'
        '      "5. sx.js fires sx:afterSwap and sx:afterSettle.")'
        '    (p :class "text-stone-600"'
        '      "6. Any sx-swap-oob elements are swapped into their targets elsewhere in the DOM."))  '
        '  (~doc-section :title "Component definitions" :id "components"'
        '    (p :class "text-stone-600"'
        '      "On full page loads, component definitions are in <script type=\\"text/sx\\" data-components>. '
        'On subsequent sx requests, missing definitions are prepended to the response body. '
        'The client caches definitions in localStorage keyed by a content hash.")))'
    )


def _protocol_fragments_sx() -> str:
    c1 = _code('(frag "blog" "link-card" :slug "hello")')
    return (
        f'(~doc-page :title "Cross-Service Fragments"'
        f'  (~doc-section :title "Fragment protocol" :id "protocol"'
        f'    (p :class "text-stone-600"'
        f'      "Rose Ash runs as independent microservices. Each service can expose HTML or sx fragments '
        f'that other services compose into their pages. Fragment endpoints return text/sx or text/html.")'
        f'    (p :class "text-stone-600"'
        f'      "The frag resolver is an I/O primitive in the render tree:")'
        f'    {c1})'
        '  (~doc-section :title "SxExpr wrapping" :id "wrapping"'
        '    (p :class "text-stone-600"'
        '      "When a fragment returns text/sx, the response is wrapped in an SxExpr and embedded directly '
        'in the render tree. When it returns text/html, it\'s wrapped in a ~rich-text component that '
        'inserts the HTML via raw!. This allows transparent composition across service boundaries."))'
        '  (~doc-section :title "fetch_fragments()" :id "fetch"'
        '    (p :class "text-stone-600"'
        '      "The Python helper fetch_fragments() fetches multiple fragments in parallel via asyncio.gather(). '
        'Fragments are cached in Redis with short TTLs. Each fragment request is HMAC-signed for authentication.")))'
    )


def _protocol_resolver_io_sx() -> str:
    return (
        '(~doc-page :title "Resolver I/O"'
        '  (~doc-section :title "Async I/O primitives" :id "primitives"'
        '    (p :class "text-stone-600"'
        '      "The sx resolver identifies I/O nodes in the render tree, groups them, '
        'executes them in parallel via asyncio.gather(), and substitutes results back in.")'
        '    (p :class "text-stone-600"'
        '      "I/O primitives:")'
        '    (ul :class "space-y-2 text-stone-600"'
        '      (li (span :class "font-mono text-violet-700" "frag") " — fetch a cross-service fragment")'
        '      (li (span :class "font-mono text-violet-700" "query") " — read data from another service")'
        '      (li (span :class "font-mono text-violet-700" "action") " — execute a write on another service")'
        '      (li (span :class "font-mono text-violet-700" "current-user") " — resolve the current authenticated user")))'
        '  (~doc-section :title "Execution model" :id "execution"'
        '    (p :class "text-stone-600"'
        '      "The render tree is walked to find I/O nodes. All nodes at the same depth are gathered '
        'and executed in parallel. Results replace the I/O nodes in the tree. The walk continues '
        'until no more I/O nodes are found. This typically completes in 1-2 passes.")))'
    )


def _protocol_internal_services_sx() -> str:
    return (
        '(~doc-page :title "Internal Services"'
        '  (~doc-note'
        '    (p "Honest note: the internal service protocol is JSON, not sx. '
        'Sx is the composition layer on top. The protocols below are the plumbing underneath."))'
        '  (~doc-section :title "HMAC-signed HTTP" :id "hmac"'
        '    (p :class "text-stone-600"'
        '      "Services communicate via HMAC-signed HTTP requests with short timeouts:")'
        '    (ul :class "space-y-2 text-stone-600 font-mono text-sm"'
        '      (li "GET /internal/data/{query} — read data (3s timeout)")'
        '      (li "POST /internal/actions/{action} — execute write (5s timeout)")'
        '      (li "POST /internal/inbox — ActivityPub-shaped event delivery")))'
        '  (~doc-section :title "fetch_data / call_action" :id "fetch"'
        '    (p :class "text-stone-600"'
        '      "Python helpers fetch_data() and call_action() handle HMAC signing, '
        'serialization, and error handling. They resolve service URLs from environment variables '
        '(INTERNAL_URL_BLOG, etc) and fall back to public URLs in development.")))'
    )


def _protocol_activitypub_sx() -> str:
    return (
        '(~doc-page :title "ActivityPub"'
        '  (~doc-note'
        '    (p "Honest note: ActivityPub wire format is JSON-LD, not sx. '
        'This documents how AP integrates with the sx rendering layer."))'
        '  (~doc-section :title "AP activities" :id "activities"'
        '    (p :class "text-stone-600"'
        '      "Rose Ash services communicate cross-domain writes via ActivityPub-shaped activities. '
        'Each service has a virtual actor. Activities are JSON-LD objects sent to /internal/inbox endpoints. '
        'RSA signatures authenticate the sender."))'
        '  (~doc-section :title "Event bus" :id "bus"'
        '    (p :class "text-stone-600"'
        '      "The event bus dispatches activities to registered handlers. '
        'Handlers are async functions that process the activity and may trigger side effects. '
        'The bus runs as a background processor in each service.")))'
    )


def _protocol_future_sx() -> str:
    return (
        '(~doc-page :title "Future Possibilities"'
        '  (~doc-note'
        '    (p "This page is speculative. Nothing here is implemented. '
        'It documents ideas that may or may not happen."))'
        '  (~doc-section :title "Custom protocol schemes" :id "schemes"'
        '    (p :class "text-stone-600"'
        '      "sx:// and sxs:// as custom URI schemes for content addressing or deep linking. '
        'An sx:// URI could resolve to an sx expression from a federated registry. '
        'This is technically feasible but practically unnecessary for a single-site deployment."))'
        '  (~doc-section :title "Sx as AP serialization" :id "ap-sx"'
        '    (p :class "text-stone-600"'
        '      "ActivityPub objects could be serialized as s-expressions instead of JSON-LD. '
        'S-expressions are more compact and easier to parse. '
        'The practical barrier: the entire AP ecosystem expects JSON-LD."))'
        '  (~doc-section :title "Sx-native federation" :id "federation"'
        '    (p :class "text-stone-600"'
        '      "Federated services could exchange sx fragments directly — render a remote user\'s '
        'profile card by fetching its sx source from their server. '
        'This requires trust and standardization that doesn\'t exist yet."))'
        '  (~doc-section :title "Realistic assessment" :id "realistic"'
        '    (p :class "text-stone-600"'
        '      "The most likely near-term improvement is sx:// deep linking for client-side component '
        'resolution. Everything else requires ecosystem adoption that one project can\'t drive alone.")))'
    )


# ---------------------------------------------------------------------------
# Examples pages
# ---------------------------------------------------------------------------

def _examples_content_sx(slug: str) -> str:
    builders = {
        "click-to-load": _example_click_to_load_sx,
        "form-submission": _example_form_submission_sx,
        "polling": _example_polling_sx,
        "delete-row": _example_delete_row_sx,
        "inline-edit": _example_inline_edit_sx,
        "oob-swaps": _example_oob_swaps_sx,
        "lazy-loading": _example_lazy_loading_sx,
        "infinite-scroll": _example_infinite_scroll_sx,
        "progress-bar": _example_progress_bar_sx,
        "active-search": _example_active_search_sx,
        "inline-validation": _example_inline_validation_sx,
        "value-select": _example_value_select_sx,
        "reset-on-submit": _example_reset_on_submit_sx,
        "edit-row": _example_edit_row_sx,
        "bulk-update": _example_bulk_update_sx,
        "swap-positions": _example_swap_positions_sx,
        "select-filter": _example_select_filter_sx,
        "tabs": _example_tabs_sx,
        "animations": _example_animations_sx,
        "dialogs": _example_dialogs_sx,
        "keyboard-shortcuts": _example_keyboard_shortcuts_sx,
        "put-patch": _example_put_patch_sx,
        "json-encoding": _example_json_encoding_sx,
        "vals-and-headers": _example_vals_and_headers_sx,
        "loading-states": _example_loading_states_sx,
        "sync-replace": _example_sync_replace_sx,
        "retry": _example_retry_sx,
    }
    return builders.get(slug, _example_click_to_load_sx)()


def _example_click_to_load_sx() -> str:
    c_sx = _example_code('(button\n'
                         '  :sx-get "/examples/api/click"\n'
                         '  :sx-target "#click-result"\n'
                         '  :sx-swap "innerHTML"\n'
                         '  "Load content")')
    c_handler = _example_code('@bp.get("/examples/api/click")\n'
                              'async def api_click():\n'
                              '    now = datetime.now().strftime(...)\n'
                              '    return sx_response(\n'
                              '        f\'(~click-result :time "{now}")\')',
                              language="python")
    return (
        f'(~doc-page :title "Click to Load"'
        f'  (p :class "text-stone-600 mb-6"'
        f'    "The simplest sx interaction: click a button, fetch content from the server, swap it in.")'
        f'  (~example-card :title "Demo"'
        f'    :description "Click the button to load server-rendered content."'
        f'    (~example-demo (~click-to-load-demo)))'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "S-expression")'
        f'  {c_sx}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Component")'
        f'  {_placeholder("click-comp")}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Server handler")'
        f'  {c_handler}'
        f'  (div :class "flex items-center justify-between mt-6"'
        f'    (h3 :class "text-lg font-semibold text-stone-700" "Wire response")'
        f'    {_clear_components_btn()})'
        f'  (p :class "text-stone-500 text-sm mb-2"'
        f'    "The server responds with content-type text/sx. New CSS rules are prepended as a style tag.'
        f' Clear the component cache to see component definitions included in the wire response.")'
        f'  {_placeholder("click-wire")})'
    )


def _example_form_submission_sx() -> str:
    c_sx = _example_code('(form\n'
                         '  :sx-post "/examples/api/form"\n'
                         '  :sx-target "#form-result"\n'
                         '  :sx-swap "innerHTML"\n'
                         '  (input :type "text" :name "name")\n'
                         '  (button :type "submit" "Submit"))')
    c_handler = _example_code('@bp.post("/examples/api/form")\n'
                              'async def api_form():\n'
                              '    form = await request.form\n'
                              '    name = form.get("name", "")\n'
                              '    return sx_response(\n'
                              '        f\'(~form-result :name "{name}")\')',
                              language="python")
    return (
        f'(~doc-page :title "Form Submission"'
        f'  (p :class "text-stone-600 mb-6"'
        f'    "Forms with sx-post submit via AJAX and swap the response into a target.")'
        f'  (~example-card :title "Demo"'
        f'    :description "Enter a name and submit."'
        f'    (~example-demo (~form-demo)))'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "S-expression")'
        f'  {c_sx}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Component")'
        f'  {_placeholder("form-comp")}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Server handler")'
        f'  {c_handler}'
        f'  (div :class "flex items-center justify-between mt-6"'
        f'    (h3 :class "text-lg font-semibold text-stone-700" "Wire response")'
        f'    {_clear_components_btn()})'
        f'  {_placeholder("form-wire")})'
    )


def _example_polling_sx() -> str:
    c_sx = _example_code('(div\n'
                         '  :sx-get "/examples/api/poll"\n'
                         '  :sx-trigger "load, every 2s"\n'
                         '  :sx-swap "innerHTML"\n'
                         '  "Loading...")')
    c_handler = _example_code('@bp.get("/examples/api/poll")\n'
                              'async def api_poll():\n'
                              '    poll_count["n"] += 1\n'
                              '    now = datetime.now().strftime("%H:%M:%S")\n'
                              '    count = min(poll_count["n"], 10)\n'
                              '    return sx_response(\n'
                              '        f\'(~poll-result :time "{now}" :count {count})\')',
                              language="python")
    return (
        f'(~doc-page :title "Polling"'
        f'  (p :class "text-stone-600 mb-6"'
        f'    "Use sx-trigger with \\"every\\" to poll the server at regular intervals.")'
        f'  (~example-card :title "Demo"'
        f'    :description "This div polls the server every 2 seconds."'
        f'    (~example-demo (~polling-demo)))'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "S-expression")'
        f'  {c_sx}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Component")'
        f'  {_placeholder("poll-comp")}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Server handler")'
        f'  {c_handler}'
        f'  (div :class "flex items-center justify-between mt-6"'
        f'    (h3 :class "text-lg font-semibold text-stone-700" "Wire response")'
        f'    {_clear_components_btn()})'
        f'  (p :class "text-stone-500 text-sm mb-2"'
        f'    "Updates every 2 seconds — watch the time and count change.")'
        f'  {_placeholder("poll-wire")})'
    )


def _example_delete_row_sx() -> str:
    from content.pages import DELETE_DEMO_ITEMS
    items_sx = " ".join(f'(list "{id}" "{name}")' for id, name in DELETE_DEMO_ITEMS)
    c_sx = _example_code('(button\n'
                         '  :sx-delete "/api/delete/1"\n'
                         '  :sx-target "#row-1"\n'
                         '  :sx-swap "outerHTML"\n'
                         '  :sx-confirm "Delete this item?"\n'
                         '  "delete")')
    c_handler = _example_code('@bp.delete("/examples/api/delete/<item_id>")\n'
                              'async def api_delete(item_id: str):\n'
                              '    # Empty response — outerHTML swap removes the row\n'
                              '    return Response("", status=200,\n'
                              '                    content_type="text/sx")',
                              language="python")
    return (
        f'(~doc-page :title "Delete Row"'
        f'  (p :class "text-stone-600 mb-6"'
        f'    "sx-delete with sx-swap \\"outerHTML\\" and an empty response removes the row from the DOM.")'
        f'  (~example-card :title "Demo"'
        f'    :description "Click delete to remove a row. Uses sx-confirm for confirmation."'
        f'    (~example-demo (~delete-demo :items (list {items_sx}))))'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "S-expression")'
        f'  {c_sx}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Component")'
        f'  {_placeholder("delete-comp")}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Server handler")'
        f'  {c_handler}'
        f'  (div :class "flex items-center justify-between mt-6"'
        f'    (h3 :class "text-lg font-semibold text-stone-700" "Wire response")'
        f'    {_clear_components_btn()})'
        f'  (p :class "text-stone-500 text-sm mb-2"'
        f'    "Empty body — outerHTML swap replaces the target element with nothing.")'
        f'  {_placeholder("delete-wire")})'
    )


def _example_inline_edit_sx() -> str:
    c_sx = _example_code(';; View mode — shows text + edit button\n'
                         '(~inline-view :value "some text")\n\n'
                         ';; Edit mode — returned by server on click\n'
                         '(~inline-edit-form :value "some text")')
    c_handler = _example_code('@bp.get("/examples/api/edit")\n'
                              'async def api_edit_form():\n'
                              '    value = request.args.get("value", "")\n'
                              '    return sx_response(\n'
                              '        f\'(~inline-edit-form :value "{value}")\')\n\n'
                              '@bp.post("/examples/api/edit")\n'
                              'async def api_edit_save():\n'
                              '    form = await request.form\n'
                              '    value = form.get("value", "")\n'
                              '    return sx_response(\n'
                              '        f\'(~inline-view :value "{value}")\')',
                              language="python")
    return (
        f'(~doc-page :title "Inline Edit"'
        f'  (p :class "text-stone-600 mb-6"'
        f'    "Click edit to swap a display view for an edit form. Save swaps back.")'
        f'  (~example-card :title "Demo"'
        f'    :description "Click edit, modify the text, save or cancel."'
        f'    (~example-demo (~inline-edit-demo)))'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "S-expression")'
        f'  {c_sx}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Components")'
        f'  {_placeholder("edit-comp")}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Server handlers")'
        f'  {c_handler}'
        f'  (div :class "flex items-center justify-between mt-6"'
        f'    (h3 :class "text-lg font-semibold text-stone-700" "Wire response")'
        f'    {_clear_components_btn()})'
        f'  {_placeholder("edit-wire")})'
    )


def _example_oob_swaps_sx() -> str:
    c_sx = _example_code(';; Button targets Box A\n'
                         '(button\n'
                         '  :sx-get "/examples/api/oob"\n'
                         '  :sx-target "#oob-box-a"\n'
                         '  :sx-swap "innerHTML"\n'
                         '  "Update both boxes")')
    c_handler = _example_code('@bp.get("/examples/api/oob")\n'
                              'async def api_oob():\n'
                              '    now = datetime.now().strftime("%H:%M:%S")\n'
                              '    return sx_response(\n'
                              '        f\'(<>\'\n'
                              '        f\'  (p "Box A updated at {now}")\'\n'
                              '        f\'  (div :id "oob-box-b"\'\n'
                              '        f\'       :sx-swap-oob "innerHTML"\'\n'
                              '        f\'    (p "Box B updated at {now}")))\')',
                              language="python")
    return (
        f'(~doc-page :title "Out-of-Band Swaps"'
        f'  (p :class "text-stone-600 mb-6"'
        f'    "sx-swap-oob lets a single response update multiple elements anywhere in the DOM.")'
        f'  (~example-card :title "Demo"'
        f'    :description "One request updates both Box A (via sx-target) and Box B (via sx-swap-oob)."'
        f'    (~example-demo (~oob-demo)))'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "S-expression")'
        f'  {c_sx}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Server handler")'
        f'  {c_handler}'
        f'  (div :class "flex items-center justify-between mt-6"'
        f'    (h3 :class "text-lg font-semibold text-stone-700" "Wire response")'
        f'    {_clear_components_btn()})'
        f'  (p :class "text-stone-500 text-sm mb-2"'
        f'    "The fragment contains both the main content and an OOB element. sx.js splits them: main content goes to sx-target, OOB elements find their targets by ID.")'
        f'  {_placeholder("oob-wire")})'
    )


def _example_lazy_loading_sx() -> str:
    c_sx = _example_code('(div\n'
                         '  :sx-get "/examples/api/lazy"\n'
                         '  :sx-trigger "load"\n'
                         '  :sx-swap "innerHTML"\n'
                         '  (div :class "animate-pulse" "Loading..."))')
    c_handler = _example_code('@bp.get("/examples/api/lazy")\n'
                              'async def api_lazy():\n'
                              '    now = datetime.now().strftime(...)\n'
                              '    return sx_response(\n'
                              '        f\'(~lazy-result :time "{now}")\')',
                              language="python")
    return (
        f'(~doc-page :title "Lazy Loading"'
        f'  (p :class "text-stone-600 mb-6"'
        f'    "Use sx-trigger=\\"load\\" to fetch content as soon as the element enters the DOM. '
        f'Great for deferring expensive content below the fold.")'
        f'  (~example-card :title "Demo"'
        f'    :description "Content loads automatically when the page renders."'
        f'    (~example-demo (~lazy-loading-demo)))'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "S-expression")'
        f'  {c_sx}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Component")'
        f'  {_placeholder("lazy-comp")}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Server handler")'
        f'  {c_handler}'
        f'  (div :class "flex items-center justify-between mt-6"'
        f'    (h3 :class "text-lg font-semibold text-stone-700" "Wire response")'
        f'    {_clear_components_btn()})'
        f'  {_placeholder("lazy-wire")})'
    )


def _example_infinite_scroll_sx() -> str:
    c_sx = _example_code('(div :id "scroll-sentinel"\n'
                         '  :sx-get "/examples/api/scroll?page=2"\n'
                         '  :sx-trigger "intersect once"\n'
                         '  :sx-target "#scroll-items"\n'
                         '  :sx-swap "beforeend"\n'
                         '  "Loading more...")')
    c_handler = _example_code('@bp.get("/examples/api/scroll")\n'
                              'async def api_scroll():\n'
                              '    page = int(request.args.get("page", 2))\n'
                              '    items = [f"Item {i}" for i in range(...)]\n'
                              '    # Include next sentinel if more pages\n'
                              '    return sx_response(items_sx + sentinel_sx)',
                              language="python")
    return (
        f'(~doc-page :title "Infinite Scroll"'
        f'  (p :class "text-stone-600 mb-6"'
        f'    "A sentinel element at the bottom uses sx-trigger=\\"intersect once\\" '
        f'to load the next page when scrolled into view. Each response appends items and a new sentinel.")'
        f'  (~example-card :title "Demo"'
        f'    :description "Scroll down in the container to load more items (5 pages total)."'
        f'    (~example-demo (~infinite-scroll-demo)))'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "S-expression")'
        f'  {c_sx}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Component")'
        f'  {_placeholder("scroll-comp")}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Server handler")'
        f'  {c_handler}'
        f'  (div :class "flex items-center justify-between mt-6"'
        f'    (h3 :class "text-lg font-semibold text-stone-700" "Wire response")'
        f'    {_clear_components_btn()})'
        f'  {_placeholder("scroll-wire")})'
    )


def _example_progress_bar_sx() -> str:
    c_sx = _example_code(';; Start the job\n'
                         '(button\n'
                         '  :sx-post "/examples/api/progress/start"\n'
                         '  :sx-target "#progress-target"\n'
                         '  :sx-swap "innerHTML")\n\n'
                         ';; Each response re-polls via sx-trigger="load"\n'
                         '(div :sx-get "/api/progress/status?job=ID"\n'
                         '  :sx-trigger "load delay:500ms"\n'
                         '  :sx-target "#progress-target"\n'
                         '  :sx-swap "innerHTML")')
    c_handler = _example_code('@bp.post("/examples/api/progress/start")\n'
                              'async def api_progress_start():\n'
                              '    job_id = str(uuid4())[:8]\n'
                              '    _jobs[job_id] = 0\n'
                              '    return sx_response(\n'
                              '        f\'(~progress-status :percent 0 :job-id "{job_id}")\')',
                              language="python")
    return (
        f'(~doc-page :title "Progress Bar"'
        f'  (p :class "text-stone-600 mb-6"'
        f'    "Start a server-side job, then poll for progress using sx-trigger=\\"load delay:500ms\\" on each response. '
        f'The bar fills up and stops when complete.")'
        f'  (~example-card :title "Demo"'
        f'    :description "Click start to begin a simulated job."'
        f'    (~example-demo (~progress-bar-demo)))'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "S-expression")'
        f'  {c_sx}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Component")'
        f'  {_placeholder("progress-comp")}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Server handler")'
        f'  {c_handler}'
        f'  (div :class "flex items-center justify-between mt-6"'
        f'    (h3 :class "text-lg font-semibold text-stone-700" "Wire response")'
        f'    {_clear_components_btn()})'
        f'  {_placeholder("progress-wire")})'
    )


def _example_active_search_sx() -> str:
    c_sx = _example_code('(input :type "text" :name "q"\n'
                         '  :sx-get "/examples/api/search"\n'
                         '  :sx-trigger "keyup delay:300ms changed"\n'
                         '  :sx-target "#search-results"\n'
                         '  :sx-swap "innerHTML"\n'
                         '  :placeholder "Search...")')
    c_handler = _example_code('@bp.get("/examples/api/search")\n'
                              'async def api_search():\n'
                              '    q = request.args.get("q", "").lower()\n'
                              '    results = [l for l in LANGUAGES if q in l.lower()]\n'
                              '    return sx_response(\n'
                              '        f\'(~search-results :items (...) :query "{q}")\')',
                              language="python")
    return (
        f'(~doc-page :title "Active Search"'
        f'  (p :class "text-stone-600 mb-6"'
        f'    "An input with sx-trigger=\\"keyup delay:300ms changed\\" debounces keystrokes and only fires when the value changes. '
        f'The server filters a list of programming languages.")'
        f'  (~example-card :title "Demo"'
        f'    :description "Type to search through 20 programming languages."'
        f'    (~example-demo (~active-search-demo)))'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "S-expression")'
        f'  {c_sx}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Component")'
        f'  {_placeholder("search-comp")}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Server handler")'
        f'  {c_handler}'
        f'  (div :class "flex items-center justify-between mt-6"'
        f'    (h3 :class "text-lg font-semibold text-stone-700" "Wire response")'
        f'    {_clear_components_btn()})'
        f'  {_placeholder("search-wire")})'
    )


def _example_inline_validation_sx() -> str:
    c_sx = _example_code('(input :type "text" :name "email"\n'
                         '  :sx-get "/examples/api/validate"\n'
                         '  :sx-trigger "blur"\n'
                         '  :sx-target "#email-feedback"\n'
                         '  :sx-swap "innerHTML"\n'
                         '  :placeholder "user@example.com")')
    c_handler = _example_code('@bp.get("/examples/api/validate")\n'
                              'async def api_validate():\n'
                              '    email = request.args.get("email", "")\n'
                              '    if "@" not in email:\n'
                              '        return sx_response(\'(~validation-error ...)\')\n'
                              '    return sx_response(\'(~validation-ok ...)\')',
                              language="python")
    return (
        f'(~doc-page :title "Inline Validation"'
        f'  (p :class "text-stone-600 mb-6"'
        f'    "Validate an email field on blur. The server checks format and whether it is taken, '
        f'returning green or red feedback inline.")'
        f'  (~example-card :title "Demo"'
        f'    :description "Enter an email and click away (blur) to validate."'
        f'    (~example-demo (~inline-validation-demo)))'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "S-expression")'
        f'  {c_sx}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Component")'
        f'  {_placeholder("validate-comp")}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Server handler")'
        f'  {c_handler}'
        f'  (div :class "flex items-center justify-between mt-6"'
        f'    (h3 :class "text-lg font-semibold text-stone-700" "Wire response")'
        f'    {_clear_components_btn()})'
        f'  {_placeholder("validate-wire")})'
    )


def _example_value_select_sx() -> str:
    c_sx = _example_code('(select :name "category"\n'
                         '  :sx-get "/examples/api/values"\n'
                         '  :sx-trigger "change"\n'
                         '  :sx-target "#value-items"\n'
                         '  :sx-swap "innerHTML"\n'
                         '  (option "Languages")\n'
                         '  (option "Frameworks")\n'
                         '  (option "Databases"))')
    c_handler = _example_code('@bp.get("/examples/api/values")\n'
                              'async def api_values():\n'
                              '    cat = request.args.get("category", "")\n'
                              '    items = VALUE_SELECT_DATA.get(cat, [])\n'
                              '    return sx_response(\n'
                              '        f\'(~value-options :items (list ...))\')',
                              language="python")
    return (
        f'(~doc-page :title "Value Select"'
        f'  (p :class "text-stone-600 mb-6"'
        f'    "Two linked selects: pick a category and the second select updates with matching items via sx-get.")'
        f'  (~example-card :title "Demo"'
        f'    :description "Select a category to populate the item dropdown."'
        f'    (~example-demo (~value-select-demo)))'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "S-expression")'
        f'  {c_sx}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Component")'
        f'  {_placeholder("values-comp")}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Server handler")'
        f'  {c_handler}'
        f'  (div :class "flex items-center justify-between mt-6"'
        f'    (h3 :class "text-lg font-semibold text-stone-700" "Wire response")'
        f'    {_clear_components_btn()})'
        f'  {_placeholder("values-wire")})'
    )


def _example_reset_on_submit_sx() -> str:
    c_sx = _example_code('(form :id "reset-form"\n'
                         '  :sx-post "/examples/api/reset-submit"\n'
                         '  :sx-target "#reset-result"\n'
                         '  :sx-swap "innerHTML"\n'
                         '  :sx-on:afterSwap "this.reset()"\n'
                         '  (input :type "text" :name "message")\n'
                         '  (button :type "submit" "Send"))')
    c_handler = _example_code('@bp.post("/examples/api/reset-submit")\n'
                              'async def api_reset_submit():\n'
                              '    form = await request.form\n'
                              '    msg = form.get("message", "")\n'
                              '    return sx_response(\n'
                              '        f\'(~reset-message :message "{msg}" :time "...")\')',
                              language="python")
    return (
        f'(~doc-page :title "Reset on Submit"'
        f'  (p :class "text-stone-600 mb-6"'
        f'    "Use sx-on:afterSwap=\\"this.reset()\\" to clear form inputs after a successful submission.")'
        f'  (~example-card :title "Demo"'
        f'    :description "Submit a message — the input resets after each send."'
        f'    (~example-demo (~reset-on-submit-demo)))'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "S-expression")'
        f'  {c_sx}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Component")'
        f'  {_placeholder("reset-comp")}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Server handler")'
        f'  {c_handler}'
        f'  (div :class "flex items-center justify-between mt-6"'
        f'    (h3 :class "text-lg font-semibold text-stone-700" "Wire response")'
        f'    {_clear_components_btn()})'
        f'  {_placeholder("reset-wire")})'
    )


def _example_edit_row_sx() -> str:
    from content.pages import EDIT_ROW_DATA
    rows_sx = " ".join(
        f'(list "{r["id"]}" "{r["name"]}" "{r["price"]}" "{r["stock"]}")'
        for r in EDIT_ROW_DATA
    )
    c_sx = _example_code('(button\n'
                         '  :sx-get "/examples/api/editrow/1"\n'
                         '  :sx-target "#erow-1"\n'
                         '  :sx-swap "outerHTML"\n'
                         '  "edit")\n\n'
                         ';; Save sends form data via POST\n'
                         '(button\n'
                         '  :sx-post "/examples/api/editrow/1"\n'
                         '  :sx-target "#erow-1"\n'
                         '  :sx-swap "outerHTML"\n'
                         '  :sx-include "#erow-1"\n'
                         '  "save")')
    c_handler = _example_code('@bp.get("/examples/api/editrow/<id>")\n'
                              'async def api_editrow_form(id):\n'
                              '    row = EDIT_ROW_DATA[id]\n'
                              '    return sx_response(\n'
                              '        f\'(~edit-row-form :id ... :name ...)\')\n\n'
                              '@bp.post("/examples/api/editrow/<id>")\n'
                              'async def api_editrow_save(id):\n'
                              '    form = await request.form\n'
                              '    return sx_response(\n'
                              '        f\'(~edit-row-view :id ... :name ...)\')',
                              language="python")
    return (
        f'(~doc-page :title "Edit Row"'
        f'  (p :class "text-stone-600 mb-6"'
        f'    "Click edit to replace a table row with input fields. Save or cancel swaps back the display row. '
        f'Uses sx-include to gather form values from the row.")'
        f'  (~example-card :title "Demo"'
        f'    :description "Click edit on any row to modify it inline."'
        f'    (~example-demo (~edit-row-demo :rows (list {rows_sx}))))'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "S-expression")'
        f'  {c_sx}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Component")'
        f'  {_placeholder("editrow-comp")}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Server handler")'
        f'  {c_handler}'
        f'  (div :class "flex items-center justify-between mt-6"'
        f'    (h3 :class "text-lg font-semibold text-stone-700" "Wire response")'
        f'    {_clear_components_btn()})'
        f'  {_placeholder("editrow-wire")})'
    )


def _example_bulk_update_sx() -> str:
    from content.pages import BULK_USERS
    users_sx = " ".join(
        f'(list "{u["id"]}" "{u["name"]}" "{u["email"]}" "{u["status"]}")'
        for u in BULK_USERS
    )
    c_sx = _example_code('(button\n'
                         '  :sx-post "/examples/api/bulk?action=activate"\n'
                         '  :sx-target "#bulk-table"\n'
                         '  :sx-swap "innerHTML"\n'
                         '  :sx-include "#bulk-form"\n'
                         '  "Activate")')
    c_handler = _example_code('@bp.post("/examples/api/bulk")\n'
                              'async def api_bulk():\n'
                              '    action = request.args.get("action")\n'
                              '    form = await request.form\n'
                              '    ids = form.getlist("ids")\n'
                              '    # Update matching users\n'
                              '    return sx_response(updated_rows)',
                              language="python")
    return (
        f'(~doc-page :title "Bulk Update"'
        f'  (p :class "text-stone-600 mb-6"'
        f'    "Select rows with checkboxes and use Activate/Deactivate buttons. '
        f'sx-include gathers checkbox values from the form.")'
        f'  (~example-card :title "Demo"'
        f'    :description "Check some rows, then click Activate or Deactivate."'
        f'    (~example-demo (~bulk-update-demo :users (list {users_sx}))))'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "S-expression")'
        f'  {c_sx}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Component")'
        f'  {_placeholder("bulk-comp")}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Server handler")'
        f'  {c_handler}'
        f'  (div :class "flex items-center justify-between mt-6"'
        f'    (h3 :class "text-lg font-semibold text-stone-700" "Wire response")'
        f'    {_clear_components_btn()})'
        f'  {_placeholder("bulk-wire")})'
    )


def _example_swap_positions_sx() -> str:
    c_sx = _example_code(';; Append to end\n'
                         '(button :sx-post "/api/swap-log?mode=beforeend"\n'
                         '  :sx-target "#swap-log" :sx-swap "beforeend"\n'
                         '  "Add to End")\n\n'
                         ';; Prepend to start\n'
                         '(button :sx-post "/api/swap-log?mode=afterbegin"\n'
                         '  :sx-target "#swap-log" :sx-swap "afterbegin"\n'
                         '  "Add to Start")\n\n'
                         ';; No swap — OOB counter update only\n'
                         '(button :sx-post "/api/swap-log?mode=none"\n'
                         '  :sx-target "#swap-log" :sx-swap "none"\n'
                         '  "Silent Ping")')
    c_handler = _example_code('@bp.post("/examples/api/swap-log")\n'
                              'async def api_swap_log():\n'
                              '    mode = request.args.get("mode")\n'
                              '    # OOB counter updates on every request\n'
                              '    oob = f\'(span :id "swap-counter" :sx-swap-oob "innerHTML" "Count: {n}")\'\n'
                              '    return sx_response(entry + oob)',
                              language="python")
    return (
        f'(~doc-page :title "Swap Positions"'
        f'  (p :class "text-stone-600 mb-6"'
        f'    "Demonstrates different swap modes: beforeend appends, afterbegin prepends, '
        f'and none skips the main swap while still processing OOB updates.")'
        f'  (~example-card :title "Demo"'
        f'    :description "Try each button to see different swap behaviours."'
        f'    (~example-demo (~swap-positions-demo)))'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "S-expression")'
        f'  {c_sx}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Server handler")'
        f'  {c_handler}'
        f'  (div :class "flex items-center justify-between mt-6"'
        f'    (h3 :class "text-lg font-semibold text-stone-700" "Wire response")'
        f'    {_clear_components_btn()})'
        f'  {_placeholder("swap-wire")})'
    )


def _example_select_filter_sx() -> str:
    c_sx = _example_code(';; Pick just the stats section from the response\n'
                         '(button\n'
                         '  :sx-get "/examples/api/dashboard"\n'
                         '  :sx-target "#filter-target"\n'
                         '  :sx-swap "innerHTML"\n'
                         '  :sx-select "#dash-stats"\n'
                         '  "Stats Only")\n\n'
                         ';; No sx-select — get the full response\n'
                         '(button\n'
                         '  :sx-get "/examples/api/dashboard"\n'
                         '  :sx-target "#filter-target"\n'
                         '  :sx-swap "innerHTML"\n'
                         '  "Full Dashboard")')
    c_handler = _example_code('@bp.get("/examples/api/dashboard")\n'
                              'async def api_dashboard():\n'
                              '    # Returns header + stats + footer\n'
                              '    # Client uses sx-select to pick sections\n'
                              '    return sx_response(\n'
                              '        \'(<> (div :id "dash-header" ...) \'\n'
                              '        \'    (div :id "dash-stats" ...) \'\n'
                              '        \'    (div :id "dash-footer" ...))\')',
                              language="python")
    return (
        f'(~doc-page :title "Select Filter"'
        f'  (p :class "text-stone-600 mb-6"'
        f'    "sx-select lets the client pick a specific section from the server response by CSS selector. '
        f'The server always returns the full dashboard — the client filters.")'
        f'  (~example-card :title "Demo"'
        f'    :description "Different buttons select different parts of the same server response."'
        f'    (~example-demo (~select-filter-demo)))'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "S-expression")'
        f'  {c_sx}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Server handler")'
        f'  {c_handler}'
        f'  (div :class "flex items-center justify-between mt-6"'
        f'    (h3 :class "text-lg font-semibold text-stone-700" "Wire response")'
        f'    {_clear_components_btn()})'
        f'  {_placeholder("filter-wire")})'
    )


def _example_tabs_sx() -> str:
    c_sx = _example_code('(button\n'
                         '  :sx-get "/examples/api/tabs/tab1"\n'
                         '  :sx-target "#tab-content"\n'
                         '  :sx-swap "innerHTML"\n'
                         '  :sx-push-url "/examples/tabs?tab=tab1"\n'
                         '  "Overview")')
    c_handler = _example_code('@bp.get("/examples/api/tabs/<tab>")\n'
                              'async def api_tabs(tab: str):\n'
                              '    content = TAB_CONTENT[tab]\n'
                              '    return sx_response(content)',
                              language="python")
    return (
        f'(~doc-page :title "Tabs"'
        f'  (p :class "text-stone-600 mb-6"'
        f'    "Tab navigation using sx-push-url to update the browser URL. '
        f'Back/forward buttons navigate between previously visited tabs.")'
        f'  (~example-card :title "Demo"'
        f'    :description "Click tabs to switch content. Watch the browser URL change."'
        f'    (~example-demo (~tabs-demo)))'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "S-expression")'
        f'  {c_sx}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Server handler")'
        f'  {c_handler}'
        f'  (div :class "flex items-center justify-between mt-6"'
        f'    (h3 :class "text-lg font-semibold text-stone-700" "Wire response")'
        f'    {_clear_components_btn()})'
        f'  {_placeholder("tabs-wire")})'
    )


def _example_animations_sx() -> str:
    c_sx = _example_code('(button\n'
                         '  :sx-get "/examples/api/animate"\n'
                         '  :sx-target "#anim-target"\n'
                         '  :sx-swap "innerHTML"\n'
                         '  "Load with animation")\n\n'
                         ';; Component uses CSS animation class\n'
                         '(defcomp ~anim-result (&key color time)\n'
                         '  (div :class "sx-fade-in ..."\n'
                         '    (style ".sx-fade-in { animation: sxFadeIn 0.5s }")\n'
                         '    (p "Faded in!")))')
    c_handler = _example_code('@bp.get("/examples/api/animate")\n'
                              'async def api_animate():\n'
                              '    colors = ["bg-violet-100", "bg-emerald-100", ...]\n'
                              '    color = random.choice(colors)\n'
                              '    return sx_response(\n'
                              '        f\'(~anim-result :color "{color}" :time "{now}")\')',
                              language="python")
    return (
        f'(~doc-page :title "Animations"'
        f'  (p :class "text-stone-600 mb-6"'
        f'    "CSS animations play on swap. The component injects a style tag with a keyframe animation '
        f'and applies the class. Each click picks a random background colour.")'
        f'  (~example-card :title "Demo"'
        f'    :description "Click to swap in content with a fade-in animation."'
        f'    (~example-demo (~animations-demo)))'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "S-expression")'
        f'  {c_sx}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Component")'
        f'  {_placeholder("anim-comp")}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Server handler")'
        f'  {c_handler}'
        f'  (div :class "flex items-center justify-between mt-6"'
        f'    (h3 :class "text-lg font-semibold text-stone-700" "Wire response")'
        f'    {_clear_components_btn()})'
        f'  {_placeholder("anim-wire")})'
    )


def _example_dialogs_sx() -> str:
    c_sx = _example_code('(button\n'
                         '  :sx-get "/examples/api/dialog"\n'
                         '  :sx-target "#dialog-container"\n'
                         '  :sx-swap "innerHTML"\n'
                         '  "Open Dialog")\n\n'
                         ';; Dialog closes by swapping empty content\n'
                         '(button\n'
                         '  :sx-get "/examples/api/dialog/close"\n'
                         '  :sx-target "#dialog-container"\n'
                         '  :sx-swap "innerHTML"\n'
                         '  "Close")')
    c_handler = _example_code('@bp.get("/examples/api/dialog")\n'
                              'async def api_dialog():\n'
                              '    return sx_response(\n'
                              '        \'(~dialog-modal :title "Confirm"\'\n'
                              '        \'  :message "Are you sure?")\')\n\n'
                              '@bp.get("/examples/api/dialog/close")\n'
                              'async def api_dialog_close():\n'
                              '    return sx_response("")',
                              language="python")
    return (
        f'(~doc-page :title "Dialogs"'
        f'  (p :class "text-stone-600 mb-6"'
        f'    "Open a modal dialog by swapping in the dialog component. Close by swapping in empty content. '
        f'Pure sx — no JavaScript library needed.")'
        f'  (~example-card :title "Demo"'
        f'    :description "Click to open a modal dialog."'
        f'    (~example-demo (~dialogs-demo)))'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "S-expression")'
        f'  {c_sx}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Component")'
        f'  {_placeholder("dialog-comp")}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Server handler")'
        f'  {c_handler}'
        f'  (div :class "flex items-center justify-between mt-6"'
        f'    (h3 :class "text-lg font-semibold text-stone-700" "Wire response")'
        f'    {_clear_components_btn()})'
        f'  {_placeholder("dialog-wire")})'
    )


def _example_keyboard_shortcuts_sx() -> str:
    c_sx = _example_code('(div :id "kbd-target"\n'
                         '  :sx-get "/examples/api/keyboard?key=s"\n'
                         '  :sx-trigger "keyup[key==\'s\'&&!event.target.matches(\'input,textarea\')] from:body"\n'
                         '  :sx-swap "innerHTML"\n'
                         '  "Press a shortcut key...")')
    c_handler = _example_code('@bp.get("/examples/api/keyboard")\n'
                              'async def api_keyboard():\n'
                              '    key = request.args.get("key", "")\n'
                              '    actions = {"s": "Search", "n": "New item", "h": "Help"}\n'
                              '    return sx_response(\n'
                              '        f\'(~kbd-result :key "{key}" :action "{actions[key]}")\')',
                              language="python")
    return (
        f'(~doc-page :title "Keyboard Shortcuts"'
        f'  (p :class "text-stone-600 mb-6"'
        f'    "Use sx-trigger with keyup event filters and from:body to listen for global keyboard shortcuts. '
        f'The filter prevents firing when typing in inputs.")'
        f'  (~example-card :title "Demo"'
        f'    :description "Press s, n, or h on your keyboard."'
        f'    (~example-demo (~keyboard-shortcuts-demo)))'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "S-expression")'
        f'  {c_sx}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Component")'
        f'  {_placeholder("kbd-comp")}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Server handler")'
        f'  {c_handler}'
        f'  (div :class "flex items-center justify-between mt-6"'
        f'    (h3 :class "text-lg font-semibold text-stone-700" "Wire response")'
        f'    {_clear_components_btn()})'
        f'  {_placeholder("kbd-wire")})'
    )


def _example_put_patch_sx() -> str:
    from content.pages import PROFILE_DEFAULT
    c_sx = _example_code(';; Replace entire resource\n'
                         '(form :sx-put "/examples/api/putpatch"\n'
                         '  :sx-target "#pp-target" :sx-swap "innerHTML"\n'
                         '  (input :name "name") (input :name "email")\n'
                         '  (button "Save All (PUT)"))')
    c_handler = _example_code('@bp.put("/examples/api/putpatch")\n'
                              'async def api_put():\n'
                              '    form = await request.form\n'
                              '    # Full replacement\n'
                              '    return sx_response(\'(~pp-view ...)\')',
                              language="python")
    n, e, r = PROFILE_DEFAULT["name"], PROFILE_DEFAULT["email"], PROFILE_DEFAULT["role"]
    return (
        f'(~doc-page :title "PUT / PATCH"'
        f'  (p :class "text-stone-600 mb-6"'
        f'    "sx-put replaces the entire resource. This example shows a profile card with an Edit All button '
        f'that sends a PUT with all fields.")'
        f'  (~example-card :title "Demo"'
        f'    :description "Click Edit All to replace the full profile via PUT."'
        f'    (~example-demo (~put-patch-demo :name "{n}" :email "{e}" :role "{r}")))'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "S-expression")'
        f'  {c_sx}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Component")'
        f'  {_placeholder("pp-comp")}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Server handler")'
        f'  {c_handler}'
        f'  (div :class "flex items-center justify-between mt-6"'
        f'    (h3 :class "text-lg font-semibold text-stone-700" "Wire response")'
        f'    {_clear_components_btn()})'
        f'  {_placeholder("pp-wire")})'
    )


def _example_json_encoding_sx() -> str:
    c_sx = _example_code('(form\n'
                         '  :sx-post "/examples/api/json-echo"\n'
                         '  :sx-target "#json-result"\n'
                         '  :sx-swap "innerHTML"\n'
                         '  :sx-encoding "json"\n'
                         '  (input :name "name" :value "Ada")\n'
                         '  (input :type "number" :name "age" :value "36")\n'
                         '  (button "Submit as JSON"))')
    c_handler = _example_code('@bp.post("/examples/api/json-echo")\n'
                              'async def api_json_echo():\n'
                              '    data = await request.get_json()\n'
                              '    body = json.dumps(data, indent=2)\n'
                              '    ct = request.content_type\n'
                              '    return sx_response(\n'
                              '        f\'(~json-result :body "{body}" :content-type "{ct}")\')',
                              language="python")
    return (
        f'(~doc-page :title "JSON Encoding"'
        f'  (p :class "text-stone-600 mb-6"'
        f'    "Use sx-encoding=\\"json\\" to send form data as a JSON body instead of URL-encoded form data. '
        f'The server echoes back what it received.")'
        f'  (~example-card :title "Demo"'
        f'    :description "Submit the form and see the JSON body the server received."'
        f'    (~example-demo (~json-encoding-demo)))'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "S-expression")'
        f'  {c_sx}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Component")'
        f'  {_placeholder("json-comp")}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Server handler")'
        f'  {c_handler}'
        f'  (div :class "flex items-center justify-between mt-6"'
        f'    (h3 :class "text-lg font-semibold text-stone-700" "Wire response")'
        f'    {_clear_components_btn()})'
        f'  {_placeholder("json-wire")})'
    )


def _example_vals_and_headers_sx() -> str:
    c_sx = _example_code(';; Send extra values with the request\n'
                         '(button\n'
                         '  :sx-get "/examples/api/echo-vals"\n'
                         '  :sx-vals "{\\\\\"source\\\\\": \\\\\"button\\\\\"}"\n'
                         '  "Send with vals")\n\n'
                         ';; Send custom headers\n'
                         '(button\n'
                         '  :sx-get "/examples/api/echo-headers"\n'
                         '  :sx-headers "{\\\\\"X-Custom-Token\\\\\": \\\\\"abc123\\\\\"}"\n'
                         '  "Send with headers")')
    c_handler = _example_code('@bp.get("/examples/api/echo-vals")\n'
                              'async def api_echo_vals():\n'
                              '    vals = dict(request.args)\n'
                              '    return sx_response(\n'
                              '        f\'(~echo-result :label "values" :items (...))\')\n\n'
                              '@bp.get("/examples/api/echo-headers")\n'
                              'async def api_echo_headers():\n'
                              '    custom = {k: v for k, v in request.headers\n'
                              '              if k.startswith("X-")}\n'
                              '    return sx_response(\n'
                              '        f\'(~echo-result :label "headers" :items (...))\')',
                              language="python")
    return (
        f'(~doc-page :title "Vals & Headers"'
        f'  (p :class "text-stone-600 mb-6"'
        f'    "sx-vals adds extra key/value pairs to the request parameters. '
        f'sx-headers adds custom HTTP headers. The server echoes back what it received.")'
        f'  (~example-card :title "Demo"'
        f'    :description "Click each button to see what the server receives."'
        f'    (~example-demo (~vals-headers-demo)))'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "S-expression")'
        f'  {c_sx}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Component")'
        f'  {_placeholder("vals-comp")}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Server handler")'
        f'  {c_handler}'
        f'  (div :class "flex items-center justify-between mt-6"'
        f'    (h3 :class "text-lg font-semibold text-stone-700" "Wire response")'
        f'    {_clear_components_btn()})'
        f'  {_placeholder("vals-wire")})'
    )


def _example_loading_states_sx() -> str:
    c_sx = _example_code(';; .sx-request class added during request\n'
                         '(style ".sx-loading-btn.sx-request {\n'
                         '  opacity: 0.7; pointer-events: none; }\n'
                         '.sx-loading-btn.sx-request .sx-spinner {\n'
                         '  display: inline-block; }\n'
                         '.sx-loading-btn .sx-spinner {\n'
                         '  display: none; }")\n\n'
                         '(button :class "sx-loading-btn"\n'
                         '  :sx-get "/examples/api/slow"\n'
                         '  :sx-target "#loading-result"\n'
                         '  (span :class "sx-spinner animate-spin" "...")\n'
                         '  "Load slow endpoint")')
    c_handler = _example_code('@bp.get("/examples/api/slow")\n'
                              'async def api_slow():\n'
                              '    await asyncio.sleep(2)\n'
                              '    return sx_response(\n'
                              '        f\'(~loading-result :time "{now}")\')',
                              language="python")
    return (
        f'(~doc-page :title "Loading States"'
        f'  (p :class "text-stone-600 mb-6"'
        f'    "sx.js adds the .sx-request CSS class to any element that has an active request. '
        f'Use pure CSS to show spinners, disable buttons, or change opacity during loading.")'
        f'  (~example-card :title "Demo"'
        f'    :description "Click the button — it shows a spinner during the 2-second request."'
        f'    (~example-demo (~loading-states-demo)))'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "S-expression")'
        f'  {c_sx}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Component")'
        f'  {_placeholder("loading-comp")}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Server handler")'
        f'  {c_handler}'
        f'  (div :class "flex items-center justify-between mt-6"'
        f'    (h3 :class "text-lg font-semibold text-stone-700" "Wire response")'
        f'    {_clear_components_btn()})'
        f'  {_placeholder("loading-wire")})'
    )


def _example_sync_replace_sx() -> str:
    c_sx = _example_code('(input :type "text" :name "q"\n'
                         '  :sx-get "/examples/api/slow-search"\n'
                         '  :sx-trigger "keyup delay:200ms changed"\n'
                         '  :sx-target "#sync-result"\n'
                         '  :sx-swap "innerHTML"\n'
                         '  :sx-sync "replace"\n'
                         '  "Type to search...")')
    c_handler = _example_code('@bp.get("/examples/api/slow-search")\n'
                              'async def api_slow_search():\n'
                              '    delay = random.uniform(0.5, 2.0)\n'
                              '    await asyncio.sleep(delay)\n'
                              '    q = request.args.get("q", "")\n'
                              '    return sx_response(\n'
                              '        f\'(~sync-result :query "{q}" :delay "{delay_ms}")\')',
                              language="python")
    return (
        f'(~doc-page :title "Request Abort"'
        f'  (p :class "text-stone-600 mb-6"'
        f'    "sx-sync=\\"replace\\" aborts any in-flight request before sending a new one. '
        f'This prevents stale responses from overwriting newer ones, even with random server delays.")'
        f'  (~example-card :title "Demo"'
        f'    :description "Type quickly — only the latest result appears despite random 0.5-2s server delays."'
        f'    (~example-demo (~sync-replace-demo)))'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "S-expression")'
        f'  {c_sx}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Component")'
        f'  {_placeholder("sync-comp")}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Server handler")'
        f'  {c_handler}'
        f'  (div :class "flex items-center justify-between mt-6"'
        f'    (h3 :class "text-lg font-semibold text-stone-700" "Wire response")'
        f'    {_clear_components_btn()})'
        f'  {_placeholder("sync-wire")})'
    )


def _example_retry_sx() -> str:
    c_sx = _example_code('(button\n'
                         '  :sx-get "/examples/api/flaky"\n'
                         '  :sx-target "#retry-result"\n'
                         '  :sx-swap "innerHTML"\n'
                         '  :sx-retry "exponential:1000:8000"\n'
                         '  "Call flaky endpoint")')
    c_handler = _example_code('@bp.get("/examples/api/flaky")\n'
                              'async def api_flaky():\n'
                              '    _flaky["n"] += 1\n'
                              '    if _flaky["n"] % 3 != 0:\n'
                              '        return Response("", status=503)\n'
                              '    return sx_response(\n'
                              '        f\'(~retry-result :attempt {n} ...)\')',
                              language="python")
    return (
        f'(~doc-page :title "Retry"'
        f'  (p :class "text-stone-600 mb-6"'
        f'    "sx-retry=\\"exponential:1000:8000\\" retries failed requests with exponential backoff '
        f'starting at 1s up to 8s. The endpoint fails the first 2 attempts and succeeds on the 3rd.")'
        f'  (~example-card :title "Demo"'
        f'    :description "Click the button — watch it retry automatically after failures."'
        f'    (~example-demo (~retry-demo)))'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "S-expression")'
        f'  {c_sx}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Component")'
        f'  {_placeholder("retry-comp")}'
        f'  (h3 :class "text-lg font-semibold text-stone-700 mt-6" "Server handler")'
        f'  {c_handler}'
        f'  (div :class "flex items-center justify-between mt-6"'
        f'    (h3 :class "text-lg font-semibold text-stone-700" "Wire response")'
        f'    {_clear_components_btn()})'
        f'  {_placeholder("retry-wire")})'
    )


# ---------------------------------------------------------------------------
# Essays
# ---------------------------------------------------------------------------

def _essay_content_sx(slug: str) -> str:
    builders = {
        "sx-sucks": _essay_sx_sucks,
        "why-sexps": _essay_why_sexps,
        "htmx-react-hybrid": _essay_htmx_react_hybrid,
        "on-demand-css": _essay_on_demand_css,
    }
    return builders.get(slug, _essay_sx_sucks)()


def _essay_sx_sucks() -> str:
    p = '(p :class "text-stone-600"'
    return (
        '(~doc-page :title "sx sucks"'
        '  (p :class "text-stone-500 text-sm italic mb-8"'
        '    "In the grand tradition of "'
        '    (a :href "https://htmx.org/essays/htmx-sucks/"'
        '       :class "text-violet-600 hover:underline" "htmx sucks"))'

        '  (~doc-section :title "The parentheses" :id "parens"'
        f'    {p}'
        '      "S-expressions are parentheses. '
        'Lots of parentheses. You thought LISP was dead? '
        'No, someone just decided to use it for HTML templates. '
        'Your IDE will need a parenthesis counter. Your code reviews will be 40% closing parens. '
        'Every merge conflict will be about whether a paren belongs on this line or the next."))'

        '  (~doc-section :title "Nobody asked for this" :id "nobody-asked"'
        f'    {p}'
        '      "The JavaScript ecosystem has React, Vue, Svelte, Solid, Qwik, and approximately '
        '47,000 other frameworks. htmx proved you can skip them all. '
        'sx looked at this landscape and said: you know what this needs? A Lisp dialect. '
        'For HTML. Over HTTP.")'
        f'    {p}'
        '      "Nobody was asking for this. The zero GitHub stars confirm it. It is not even on GitHub."))'

        '  (~doc-section :title "The author has never written a line of LISP" :id "no-lisp"'
        f'    {p}'
        '      "The author of sx has never written a single line of actual LISP. '
        'Not Common Lisp. Not Scheme. Not Clojure. Not even Emacs Lisp. '
        'The entire s-expression evaluator was written by someone whose mental model of LISP '
        'comes from reading the first three chapters of SICP and then closing the tab.")'
        f'    {p}'
        '      "This is like building a sushi restaurant when your only experience with Japanese '
        'cuisine is eating supermarket California rolls."))'

        '  (~doc-section :title "AI wrote most of it" :id "ai"'
        f'    {p}'
        '      "A significant portion of sx — '
        'the evaluator, the parser, the primitives, the CSS scanner, this very documentation site — '
        'was written with AI assistance. The author typed prompts. Claude typed code. '
        'This is not artisanal hand-crafted software. This is the software equivalent of '
        'a microwave dinner presented on a nice plate.")'
        f'    {p}'
        '      "He adds features by typing stuff like '
        '\\"is there rom for macros within sx.js?  what benefits m,ight that bring?\\", '
        'skim-reading the response, and then entering \\"crack on then!\\" '
        'This is not software engineering. This is improv comedy with a compiler.")'
        f'    {p}'
        '      "Is that bad? Maybe. Is it honest? Yes. Is this paragraph also AI-generated? '
        'You will never know."))'

        '  (~doc-section :title "No ecosystem" :id "ecosystem"'
        f'    {p}'
        '      "npm has 2 million packages. PyPI has 500,000. '
        'sx has zero packages, zero plugins, zero middleware, zero community, '
        'zero Stack Overflow answers, and zero conference talks. '
        'If you get stuck, your options are: read the source, or ask the one person who wrote it.")'
        f'    {p}'
        '      "That person is busy. Good luck."))'

        '  (~doc-section :title "Zero jobs" :id "jobs"'
        f'    {p}'
        '      "Adding sx to your CV will not get you hired. It will get you questioned.")'
        f'    {p}'
        '      "The interview will end shortly after."))'

        '  (~doc-section :title "The creator thinks s-expressions are a personality trait" :id "personality"'
        f'    {p}'
        '      "Look at this documentation site. It has a violet colour scheme. '
        'It has credits to htmx. It has a future possibilities page about hypothetical '
        'sx:// protocol schemes. The creator built an entire microservice — with Docker, Redis, '
        'and a custom entrypoint script — just to serve documentation about a rendering engine '
        'that runs one website.")'
        f'    {p}'
        '      "This is not engineering. This is a personality disorder expressed in YAML.")))'
    )


def _essay_why_sexps() -> str:
    return (
        '(~doc-page :title "Why S-Expressions Over HTML Attributes"'
        '  (~doc-section :title "The problem with HTML attributes" :id "problem"'
        '    (p :class "text-stone-600"'
        '      "HTML attributes are strings. You can put anything in a string. '
        'htmx puts DSLs in strings — trigger modifiers, swap strategies, CSS selectors. '
        'This works but it means you\'re parsing a language within a language within a language.")'
        '    (p :class "text-stone-600"'
        '      "S-expressions are already structured. Keywords are keywords. Lists are lists. '
        'Nested expressions nest naturally. There\'s no need to invent a trigger modifier syntax '
        'because the expression language already handles composition."))'
        '  (~doc-section :title "Components without a build step" :id "components"'
        '    (p :class "text-stone-600"'
        '      "React showed that components are the right abstraction for UI. '
        'The price: a build step, a bundler, JSX transpilation. '
        'With s-expressions, defcomp is just another form in the language. '
        'No transpiler needed. The same source runs on server and client."))'
        '  (~doc-section :title "When attributes are better" :id "better"'
        '    (p :class "text-stone-600"'
        '      "HTML attributes work in any HTML document. S-expressions need a runtime. '
        'If you want progressive enhancement that works with JS disabled, htmx is better. '
        'If you want to write HTML by hand in static files, htmx is better. '
        'sx only makes sense when you\'re already rendering server-side and want components.")))'
    )


def _essay_htmx_react_hybrid() -> str:
    return (
        '(~doc-page :title "The htmx/React Hybrid"'
        '  (~doc-section :title "Two good ideas" :id "ideas"'
        '    (p :class "text-stone-600"'
        '      "htmx: the server should render HTML. The client should swap it in. '
        'No client-side routing. No virtual DOM. No state management.")'
        '    (p :class "text-stone-600"'
        '      "React: UI should be composed from reusable components with parameters. '
        'Components encapsulate structure, style, and behavior.")'
        '    (p :class "text-stone-600"'
        '      "sx tries to combine both: server-rendered s-expressions with hypermedia attributes '
        'AND a component model with caching and composition."))'
        '  (~doc-section :title "What sx keeps from htmx" :id "from-htmx"'
        '    (ul :class "space-y-2 text-stone-600"'
        '      (li "Server generates the UI — no client-side data fetching or state")'
        '      (li "Hypermedia attributes (sx-get, sx-target, sx-swap) on any element")'
        '      (li "Partial page updates via swap/OOB — no full page reloads")'
        '      (li "Works with standard HTTP — no WebSocket or custom protocol required")))'
        '  (~doc-section :title "What sx adds from React" :id "from-react"'
        '    (ul :class "space-y-2 text-stone-600"'
        '      (li "defcomp — named, parameterized, composable components")'
        '      (li "Client-side rendering — server sends source, client renders DOM")'
        '      (li "Component caching — definitions cached in localStorage across navigations")'
        '      (li "On-demand CSS — only ship the rules that are used")))'
        '  (~doc-section :title "What sx gives up" :id "gives-up"'
        '    (ul :class "space-y-2 text-stone-600"'
        '      (li "No HTML output — sx sends s-expressions, not HTML. JS required.")'
        '      (li "Custom parser — the client needs sx.js to understand responses")'
        '      (li "Niche — no ecosystem, no community, no third-party support")'
        '      (li "Learning curve — s-expression syntax is unfamiliar to most web developers"))))'
    )


def _essay_on_demand_css() -> str:
    return (
        '(~doc-page :title "On-Demand CSS: Killing the Tailwind Bundle"'
        '  (~doc-section :title "The problem" :id "problem"'
        '    (p :class "text-stone-600"'
        '      "Tailwind CSS generates a utility class for every possible combination. '
        'The full CSS file is ~4MB. The purged output for a typical site is 20-50KB. '
        'Purging requires a build step that scans your source files for class names. '
        'This means: a build tool, a config file, a CI step, and a prayer that the scanner '
        'finds all your dynamic classes."))'
        '  (~doc-section :title "The sx approach" :id "approach"'
        '    (p :class "text-stone-600"'
        '      "sx takes a different path. At server startup, the full Tailwind CSS file is parsed '
        'into a dictionary keyed by class name. When rendering a response, sx scans the s-expression '
        'source for :class attribute values and looks up only those classes. '
        'The result: exact CSS, zero build step.")'
        '    (p :class "text-stone-600"'
        '      "Component definitions are pre-scanned at registration time. '
        'Page-specific sx is scanned at request time. The union of classes is resolved to CSS rules."))'
        '  (~doc-section :title "Incremental delivery" :id "incremental"'
        '    (p :class "text-stone-600"'
        '      "After the first page load, the client tracks which CSS classes it already has. '
        'On subsequent navigations, it sends a hash of its known classes in the SX-Css header. '
        'The server computes the diff and sends only new rules. '
        'A typical navigation adds 0-10 new rules — a few hundred bytes at most."))'
        '  (~doc-section :title "The tradeoff" :id "tradeoff"'
        '    (p :class "text-stone-600"'
        '      "The server holds ~4MB of parsed CSS in memory. '
        'Regex scanning is not perfect — dynamically constructed class names '
        'will not be found. In practice this rarely matters because sx components '
        'use mostly static class strings.")))'
    )


# ---------------------------------------------------------------------------
# Wire-format partials (for sx-get requests)
# ---------------------------------------------------------------------------

def home_content_sx() -> str:
    """Home page content as sx wire format."""
    hero_code = highlight('(div :class "p-4 bg-white rounded shadow"\n'
                          '  (h1 :class "text-2xl font-bold" "Hello")\n'
                          '  (button :sx-get "/api/data"\n'
                          '    :sx-target "#result"\n'
                          '    "Load data"))', "lisp")
    return (
        f'(section :id "main-panel"'
        f'  :class "flex-1 md:h-full md:min-h-0 overflow-y-auto overscroll-contain js-grid-viewport"'
        f'  (div :id "main-content"'
        f'    (~sx-hero {hero_code})'
        f'    (~sx-philosophy)'
        f'    (~sx-how-it-works)'
        f'    (~sx-credits)))'
    )


def docs_content_partial_sx(slug: str) -> str:
    """Docs content as sx wire format."""
    inner = _docs_content_sx(slug)
    return (
        f'(section :id "main-panel"'
        f'  :class "flex-1 md:h-full md:min-h-0 overflow-y-auto overscroll-contain js-grid-viewport"'
        f'  {inner})'
    )


def reference_content_partial_sx(slug: str) -> str:
    inner = _reference_content_sx(slug)
    return (
        f'(section :id "main-panel"'
        f'  :class "flex-1 md:h-full md:min-h-0 overflow-y-auto overscroll-contain js-grid-viewport"'
        f'  {inner})'
    )


def protocol_content_partial_sx(slug: str) -> str:
    inner = _protocol_content_sx(slug)
    return (
        f'(section :id "main-panel"'
        f'  :class "flex-1 md:h-full md:min-h-0 overflow-y-auto overscroll-contain js-grid-viewport"'
        f'  {inner})'
    )


def examples_content_partial_sx(slug: str) -> str:
    inner = _examples_content_sx(slug)
    return (
        f'(section :id "main-panel"'
        f'  :class "flex-1 md:h-full md:min-h-0 overflow-y-auto overscroll-contain js-grid-viewport"'
        f'  {inner})'
    )


def essay_content_partial_sx(slug: str) -> str:
    inner = _essay_content_sx(slug)
    return (
        f'(section :id "main-panel"'
        f'  :class "flex-1 md:h-full md:min-h-0 overflow-y-auto overscroll-contain js-grid-viewport"'
        f'  {inner})'
    )
