<https://docs.linkeddatahub.com/reference/stylesheets/>
        a       <https://w3id.org/atomgraph/linkeddatahub/document-hierarchy#Item>;
        <http://www.w3.org/1999/02/22-rdf-syntax-ns#_1>
                <https://docs.linkeddatahub.com/reference/stylesheets/#content>;
        <http://purl.org/dc/terms/created>
                "2026-10-25T17:34:29.572Z"^^<http://www.w3.org/2001/XMLSchema#dateTime>;
        <http://purl.org/dc/terms/creator>
                <https://admin.linkeddatahub.com/acl/agents/01fe43e2-f80e-4312-b37e-86063a80e4f9/#this>;
        <http://purl.org/dc/terms/description>
                "Built-in XSLT, CSS and JavaScript assets, and how to override them";
        <http://purl.org/dc/terms/modified>
                "2026-10-27T12:16:57.002Z"^^<http://www.w3.org/2001/XMLSchema#dateTime>;
        <http://purl.org/dc/terms/title>
                "Stylesheets";
        <http://rdfs.org/sioc/ns#has_container>
                <https://docs.linkeddatahub.com/reference/>;
        <http://www.w3.org/ns/auth/acl#owner>
                <https://admin.linkeddatahub.com/acl/agents/01fe43e2-f80e-4312-b37e-86063a80e4f9/#this> .

<https://docs.linkeddatahub.com/reference/stylesheets/#content>
        a       <https://w3id.org/atomgraph/linkeddatahub#XHTML>;
        <http://www.w3.org/1999/02/22-rdf-syntax-ns#value>
                "<div xmlns=\"http://www.w3.org/1999/xhtml\">\n    <p class=\"ldh-body-lg\">Built-in XSLT, CSS and JavaScript assets, and how to override them</p>\n    <div>\n        <h2 id=\"xslt\">XSLT</h2>\n        <p>XSLT is a functional, Turing-complete XML transformation language.</p>\n        <p>LinkedDataHub's <a href=\"https://www.w3.org/TR/xslt-30/\" target=\"_blank\">XSLT 3.0</a> stylesheets work by transforming the <a href=\"https://www.w3.org/TR/rdf-syntax-grammar/\" target=\"_blank\">RDF/XML</a> response body from the underlying <a href=\"../http-api/\" target=\"_blank\">HTTP API</a>. Additional metadata from RDF vocabularies is used to improve the user experience.</p>\n        <div>\n            <h3 id=\"rdf-xml-plain\">Plain RDF/XML</h3>\n            <p><a href=\"https://www.w3.org/TR/rdf-syntax-grammar/\" target=\"_blank\">RDF/XML</a> is an important RDF syntax which functions as a bridge to the XML technology stack. The stylesheets use Jena's <a href=\"https://jena.apache.org/documentation/io/rdfxml_howto.html#rdfxml-rdfxml-abbrev\" target=\"_blank\">\"plain\" RDF/XML</a> output which groups statements by subject and does not nest resource descriptions. This allows for predictable XPath patterns:</p>\n            <table>\n                <caption class=\"ac-vh\">XPath expressions and what they match in RDF/XML</caption>\n                <thead>\n                    <tr>\n                        <th scope=\"col\">XPath</th>\n                        <th scope=\"col\">Represents</th>\n                    </tr>\n                </thead>\n                <tbody>\n                    <tr>\n                        <td><code>/rdf:RDF</code></td>\n                        <td>The RDF graph</td>\n                    </tr>\n                    <tr>\n                        <td><code>/rdf:RDF/rdf:Description</code> or <code>/rdf:RDF/*[*][@rdf:about] | /rdf:RDF/*[*][@rdf:nodeID]</code></td>\n                        <td>Resource description which contains properties</td>\n                    </tr>\n                    <tr>\n                        <td><code>/rdf:RDF/rdf:Description/@rdf:about</code></td>\n                        <td>Subject resource URI</td>\n                    </tr>\n                    <tr>\n                        <td><code>/rdf:RDF/rdf:Description/@rdf:nodeID</code></td>\n                        <td>Subject blank node ID</td>\n                    </tr>\n                    <tr>\n                        <td><code>/rdf:RDF/rdf:Description/*</code></td>\n                        <td>Predicate (e.g. <code>rdf:type</code>) whose URI is <code>concat(namespace-uri(), local-name())</code></td>\n                    </tr>\n                    <tr>\n                        <td><code>/rdf:RDF/rdf:Description/*/@rdf:resource</code></td>\n                        <td>Object resource</td>\n                    </tr>\n                    <tr>\n                        <td><code>/rdf:RDF/rdf:Description/*/@rdf:nodeID</code></td>\n                        <td>Object blank node ID</td>\n                    </tr>\n                    <tr>\n                        <td><code>/rdf:RDF/rdf:Description/*/text()</code></td>\n                        <td>Literal value</td>\n                    </tr>\n                </tbody>\n            </table>\n            <p>The Northwind Chai product in that shape — the input that the templates match:</p>\n            <pre>&lt;rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns:schema=\"https://schema.org/\"&gt;\n    &lt;rdf:Description rdf:about=\"https://localhost:4443/products/1/#this\"&gt;\n        &lt;rdf:type rdf:resource=\"https://schema.org/Product\"/&gt;\n        &lt;schema:name&gt;Chai&lt;/schema:name&gt;\n        &lt;schema:category rdf:resource=\"https://localhost:4443/categories/1/#this\"/&gt;\n        &lt;schema:provider rdf:resource=\"https://localhost:4443/suppliers/1/#this\"/&gt;\n    &lt;/rdf:Description&gt;\n&lt;/rdf:RDF&gt;</pre>\n        </div>\n        <div>\n            <h3 id=\"stylesheet-structure\">Stylesheet structure</h3>\n            <p>XSLT stylesheet components used by LinkedDataHub:</p>\n            <dl>\n                <dt>Includes</dt>\n                <dd><code>&lt;xsl:include&gt;</code> is used to include one stylesheet into another. The inclusion mechanism is specified in <a href=\"https://www.w3.org/TR/xslt-30/#include\" target=\"_blank\">3.10.2 Stylesheet Inclusion</a> of the XSLT 3.0 specification. The templates from the included stylesheets have the same priority as those of the including stylesheet.</dd>\n                <dt>Imports</dt>\n                <dd><code>&lt;xsl:import&gt;</code> is used to import one stylesheet into another. The import mechanism is specified in <a href=\"https://www.w3.org/TR/xslt-30/#import\" target=\"_blank\">3.10.3 Stylesheet Import</a> of the XSLT 3.0 specification. The templates from the imported stylesheets have lower priority than those of the importing stylesheet.</dd>\n                <dt>Parameters</dt>\n                <dd>XSD-typed <a href=\"#parameters\">global parameters</a> passed to the stylesheet</dd>\n                <dt>Keys</dt>\n                <dd>Lookup <a href=\"#keys\">keys</a></dd>\n                <dt>Templates</dt>\n                <dd><a href=\"#templates\">Template rules</a> for XML node processing</dd>\n            </dl>\n            <p>One XSLT stylesheet can be specified per dataspace. In order to reuse LinkedDataHub's built-in templates, it should import the <a href=\"https://github.com/AtomGraph/LinkedDataHub/blob/develop/src/main/webapp/static/com/atomgraph/linkeddatahub/xsl/layout.xsl\" target=\"_blank\">system stylesheet <samp>layout.xsl</samp></a> and only override the necessary templates. That is not a requirement, however; a stylesheet can also use its own independent transformation logic.</p>\n            <p>If there is no stylesheet specified for the dataspace, the system stylesheet is used. It defines the overall layout and imports resource-level and container-specific stylesheets, as well as per-vocabulary stylesheets.</p>\n            <p>Note that LinkedDataHub itself imports stylesheets from <a href=\"https://github.com/AtomGraph/Web-Client\" target=\"_blank\">Web-Client</a>, which uses the same template modes but produces a much simpler layout.</p>\n            <p>The same XSLT 3.0 stylesheets run in two environments. On the server they are executed by Saxon-HE to produce the initial HTML response. In the browser they are executed by <a href=\"https://www.saxonica.com/saxon-js/index.xml\" target=\"_blank\">Saxon-JS 3</a>, which provides IXSL (<a href=\"https://www.saxonica.com/saxonjs/documentation3/index.html#!ixsl-extension\" target=\"_blank\">Interactive XSLT extensions</a>) for reading and manipulating the browser DOM.</p>\n            <p>There is a dedicated <a href=\"https://github.com/AtomGraph/LinkedDataHub/blob/develop/src/main/webapp/static/com/atomgraph/linkeddatahub/xsl/client.xsl\" target=\"_blank\">client-side stylesheet <samp>client.xsl</samp></a> that drives the browser. After the server-rendered page loads, its <code>main</code> template renders the layout client-side — the left sidebar, navigation, document and tab panes, content blocks, forms and modal dialogs are injected into the DOM using IXSL (e.g. <code>ixsl:append-content</code>). It also handles all subsequent navigation, so following links and switching documents re-renders in place without a full page reload. It imports and reuses the same document-, resource- and property-level templates as the server-side system stylesheet, but avoids loading per-vocabulary stylesheets in order to improve page load time. Templates of the client-side stylesheet can also be overridden.</p>\n        </div>\n        <div>\n            <h3 id=\"namespaces\">Namespaces</h3>\n            <table>\n                <caption class=\"ac-vh\">Namespace prefixes and their vocabularies</caption>\n                <thead>\n                    <tr>\n                        <th scope=\"col\">Prefix</th>\n                        <th scope=\"col\">Namespace</th>\n                        <th scope=\"col\">Vocabulary</th>\n                        <th scope=\"col\">Description</th>\n                    </tr>\n                </thead>\n                <tbody>\n                    <tr>\n                        <td><code>rdf:</code></td>\n                        <td><code>http://www.w3.org/1999/02/22-rdf-syntax-ns#</code></td>\n                        <td><a href=\"https://www.w3.org/TR/rdf11-concepts/#vocabularies\" target=\"_blank\">The RDF Concepts Vocabulary</a></td>\n                        <td>Namespace for the <a href=\"https://www.w3.org/TR/rdf-syntax-grammar/\" target=\"_blank\">RDF/XML</a> elements, mostly used for matching input data</td>\n                    </tr>\n                    <tr>\n                        <td><code>srx:</code></td>\n                        <td><code>http://www.w3.org/2005/sparql-results#</code></td>\n                        <td><a href=\"https://www.w3.org/TR/rdf-sparql-XMLres/\" target=\"_blank\">SPARQL Query Results XML Format</a></td>\n                        <td>Namespace for the <a href=\"https://www.w3.org/TR/rdf-sparql-XMLres/\" target=\"_blank\">SPARQL Query Results XML</a> elements, mostly used for matching input data</td>\n                    </tr>\n                    <tr>\n                        <td><code>xsl:</code></td>\n                        <td><code>http://www.w3.org/1999/XSL/Transform</code></td>\n                        <td><a href=\"https://www.w3.org/TR/xslt-30/\" target=\"_blank\">XSL Transformations (XSLT) 3.0</a></td>\n                        <td>Namespace for the XSLT stylesheet elements</td>\n                    </tr>\n                    <tr>\n                        <td><code>ixsl:</code></td>\n                        <td><code>http://saxonica.com/ns/interactiveXSLT</code></td>\n                        <td><a href=\"https://www.saxonica.com/saxonjs/documentation3/index.html#!ixsl-extension\" target=\"_blank\">Saxon Interactive XSLT extensions</a></td>\n                        <td>Namespace for the <a href=\"https://www.saxonica.com/saxonjs/documentation3/index.html#!ixsl-extension\" target=\"_blank\">Interactive XSL extensions</a></td>\n                    </tr>\n                    <tr>\n                        <td><code>ldh:</code></td>\n                        <td><code>https://w3id.org/atomgraph/linkeddatahub#</code></td>\n                        <td>LinkedDataHub vocabulary</td>\n                        <td>LinkedDataHub concepts, also used for LinkedDataHub's own component template modes (named after the design system's components)</td>\n                    </tr>\n                    <tr>\n                        <td><code>xhtml:</code></td>\n                        <td><code>http://www.w3.org/1999/xhtml</code></td>\n                        <td><a href=\"https://www.w3.org/TR/xhtml1/\" target=\"_blank\">XHTML 1.0</a></td>\n                        <td>XHTML namespace, also used for generic (X)HTML templates</td>\n                    </tr>\n                    <tr>\n                        <td><code>ac:</code></td>\n                        <td><code>https://w3id.org/atomgraph/client#</code></td>\n                        <td><a href=\"https://github.com/AtomGraph/Web-Client\" target=\"_blank\">Web-Client</a> vocabulary</td>\n                        <td>Client-side concepts</td>\n                    </tr>\n                    <tr>\n                        <td><code>lds:</code></td>\n                        <td><code>https://w3id.org/atomgraph/linkeddatahub/dataspaces#</code></td>\n                        <td><a href=\"../administration/ontologies/#lds-ont\" target=\"_blank\">LinkedDataHub dataspace ontology</a></td>\n                        <td>LinkedDataHub dataspace concepts</td>\n                    </tr>\n                    <tr>\n                        <td><code>lacl:</code></td>\n                        <td><code>https://w3id.org/atomgraph/linkeddatahub/admin/acl#</code></td>\n                        <td><a href=\"../administration/ontologies/#lacl-ont\" target=\"_blank\">LinkedDataHub ACL ontology</a></td>\n                        <td>ACL concepts</td>\n                    </tr>\n                </tbody>\n            </table>\n        </div>\n        <div>\n            <h3 id=\"templates\">Templates</h3>\n            <p>XSLT template components:</p>\n            <dl>\n                <dt>Match</dt>\n                <dd>XPath-based match pattern which either does or does not match an XML node</dd>\n                <dt>Mode</dt>\n                <dd>Groups templates and distinguishes them from other groups that share the same match patterns (e.g. different layout modes)</dd>\n                <dt>Parameters</dt>\n                <dd>XSD-typed parameters passed to the template invocation</dd>\n                <dt>Body</dt>\n                <dd>Contains the XML output nodes as well as XSLT processing instructions</dd>\n            </dl>\n            <p>XSLT processing starts at the root of the RDF/XML document and produces HTML elements by applying templates to all of the RDF/XML nodes while moving down the XML tree.\n                In other words, it starts at the graph level, moves down to resource description elements, then to property elements, and ends with identifier attributes and literal text nodes.</p>\n            <p>Templates are applied (invoked) using <code>&lt;xsl:apply-templates&gt;</code>. Mode can be specified, e.g. <code>&lt;xsl:apply-templates mode=\"ac:BlockHeader\"&gt;</code>. To stay in the current mode without explicitly specifying it, use <code>&lt;xsl:apply-templates mode=\"#current\"&gt;</code>. <code>&lt;xsl:with-param&gt;</code> is used to supply parameters.</p>\n            <p>LinkedDataHub provides the following default template modes, which are used to render the <a href=\"../user-interface/#layout-modes\" target=\"_blank\">layout modes</a>:</p>\n            <ul>\n                <li>Graph-level modes that apply to <code>rdf:RDF</code>\n                    <ul>\n                        <li><dfn>default mode</dfn> renders full resource descriptions</li>\n                        <li><code>ac:List</code> renders a list of resources</li>\n                        <li><code>ac:ResultsTable</code> renders a table with resources as rows and properties as columns</li>\n                        <li><code>ac:Grid</code> renders a gallery of thumbnails</li>\n                        <li><code>ac:Map</code> renders resources with coordinates on a map</li>\n                        <li><code>ac:Graph</code> renders the resources as a node-and-edge graph</li>\n                        <li><code>ac:ResourceForm</code> renders an <a href=\"https://atomgraph.github.io/RDF-POST/\" target=\"_blank\">RDF/POST</a> form for creating new resources or editing an existing one</li>\n                    </ul>\n                </li>\n                <li>Resource-level template modes that apply to <code>rdf:Description</code>\n                    <ul>\n                        <li>default mode renders one full resource description (by default header and property list)</li>\n                        <li><code>ac:BlockHeader</code> renders resource header (by default with type information)</li>\n                        <li><code>ac:PropertyEditor</code> renders definition list with property names and values (by default grouped by resource types)</li>\n                    </ul>\n                </li>\n            </ul>\n            <p>When adding new user-defined modes, it is recommended to choose a new <a href=\"#namespaces\">namespace</a> for them as well as a user-defined prefix.</p>\n            <p>An example of a template that matches <code>rdf:Description</code>:</p>\n            <pre>&lt;xsl:template match=\"*[*][@rdf:about] | *[*][@rdf:nodeID]\"&gt;\n    &lt;xsl:param name=\"id\" as=\"xs:string?\"/&gt;\n    &lt;xsl:param name=\"class\" as=\"xs:string?\"/&gt;\n\n    &lt;div&gt;\n        &lt;xsl:if test=\"$id\"&gt;\n            &lt;xsl:attribute name=\"id\" select=\"$id\"/&gt;\n        &lt;/xsl:if&gt;\n        &lt;xsl:if test=\"$class\"&gt;\n            &lt;xsl:attribute name=\"class\" select=\"$class\"/&gt;\n        &lt;/xsl:if&gt;\n\n        &lt;xsl:apply-templates select=\".\" mode=\"ac:BlockHeader\"/&gt;\n\n        &lt;xsl:apply-templates select=\".\" mode=\"ac:PropertyEditor\"/&gt;\n    &lt;/div&gt;\n&lt;/xsl:template&gt;</pre>\n            <p>Applied to the <a href=\"#rdf-xml-plain\">Chai description above</a>, it produces markup of this shape (abridged):</p>\n            <pre>&lt;div about=\"https://localhost:4443/products/1/#this\" typeof=\"https://schema.org/Product\"&gt;\n    &lt;h2&gt;Chai&lt;/h2&gt;\n    &lt;dl&gt;\n        &lt;dt&gt;Name&lt;/dt&gt;\n        &lt;dd&gt;Chai&lt;/dd&gt;\n        &lt;dt&gt;Category&lt;/dt&gt;\n        &lt;dd&gt;&lt;a href=\"https://localhost:4443/categories/1/#this\"&gt;Beverages&lt;/a&gt;&lt;/dd&gt;\n        &lt;dt&gt;Provider&lt;/dt&gt;\n        &lt;dd&gt;&lt;a href=\"https://localhost:4443/suppliers/1/#this\"&gt;Exotic Liquids&lt;/a&gt;&lt;/dd&gt;\n    &lt;/dl&gt;\n&lt;/div&gt;</pre>\n            <p class=\"exhibit-links\">Live: <a href=\"https://northwind-traders.demo.linkeddatahub.com/products/1/\" target=\"_blank\">/products/1/</a> — the same description, rendered by the full stylesheet</p>\n            <p><code>ldh:ContentList</code> mode renders the content specified by the <code>rdf:_1</code>, <code>rdf:_2</code>, … values of the current document.</p>\n            <p>There are a few special template modes such as <code>ac:label</code> and <code>ac:description</code>, together with the related <code>ac:label()</code> and <code>ac:description()</code> functions, which are\n                used not to render layout but to extract metadata from resource descriptions. They can be used to retrieve a resource label and description no matter which RDF\n                vocabularies are used in the data. They do so by invoking templates of the respective mode from vocabulary-specific stylesheets.</p>\n        </div>\n        <div>\n            <h3 id=\"overriding-templates\">Overriding templates</h3>\n            <p>Templates are overridden by redefining them in the importing stylesheet and providing the same or more specific match pattern and the same mode. The XSLT specification defines exactly how template priorities are determined in <a href=\"https://www.w3.org/TR/xslt-30/#conflict\" target=\"_blank\">6.4 Conflict Resolution for Template Rules</a>.</p>\n            <p>The overriding template can then get the output of the overridden template by invoking either <code>&lt;xsl:apply-imports&gt;</code> or <code>&lt;xsl:next-match&gt;</code>. Read more in <a href=\"https://www.w3.org/TR/xslt-30/#apply-imports\" target=\"_blank\">6.7 Overriding Template Rules</a>.</p>\n            <p>Always override the most specific template, i.e. if you want to change how a property is rendered, do not override the template for the resource description — override only the one for the property.</p>\n        </div>\n        <div>\n            <h3 id=\"keys\">Keys</h3>\n            <p>Keys are a lookup mechanism. They are defined on the stylesheet level using <a href=\"https://www.w3.org/TR/xslt-30/#dt-key\" target=\"_blank\"><code>&lt;xsl:key&gt;</code></a> and invoked using the\n                <a href=\"https://www.w3.org/TR/xslt-30/#function-key\" target=\"_blank\"><code>key()</code></a> function. For example:</p>\n            <pre>&lt;xsl:key name=\"resources\" match=\"*[*][@rdf:about] | *[*][@rdf:nodeID]\" use=\"@rdf:about | @rdf:nodeID\"/&gt;\n\n&lt;xsl:template match=\"*\"&gt;\n    &lt;xsl:for-each select=\"key('resources', ldh:base-uri(.))\"&gt;\n        &lt;xsl:value-of select=\"ac:label(.)\"/&gt;\n    &lt;/xsl:for-each&gt;\n&lt;/xsl:template&gt;</pre>\n            <p>The key definition matches <code>rdf:Description</code> elements and uses their identifiers (URI or blank node ID). The template then looks up the RDF description of the <em>current resource</em>, i.e. the resource with URI that equals <code>ldh:base-uri(.)</code> which is the absolute URI of the current document, and outputs its label.</p>\n        </div>\n        <div>\n            <h3 id=\"loading-data\">Loading data</h3>\n            <p>The stylesheet processes one main RDF/XML document at a time, supplied by LinkedDataHub's HTML writer. However, it is possible to load additional XML documents over HTTP\n                using the <a href=\"https://www.w3.org/TR/xslt-30/#function-document\" target=\"_blank\"><code>document()</code></a> XSLT function. To avoid XSLT errors on any possible error responses, it is advisable\n                to do a conditional check using the <a href=\"https://www.w3.org/TR/xpath-functions/#func-doc-available\" target=\"_blank\"><code>doc-available()</code></a> function before doing the actual <code>document()</code> call.</p>\n            <p>For example, instead of hardcoding the title of this document as <samp>Stylesheets</samp>, you can use the following code to load it and output it on the fly:</p>\n            <pre>&lt;xsl:value-of select=\"key('resources', 'https://docs.linkeddatahub.com/reference/stylesheets/', document('https://docs.linkeddatahub.com/reference/stylesheets/'))\"/&gt;</pre>\n            <p>In case this document changes its title, all such references would automatically render the updated title. On the other hand, it incurs the overhead of making an HTTP request.</p>\n            <p>LinkedDataHub's default stylesheets use this feature extensively. In fact, one HTML page is rendered from a dozen RDF/XML documents.</p>\n            <p>The descriptions of the instance's dataspaces are available through the <code>lds:context()</code> function, which returns the\n                <a href=\"../dataspace/#context\">dataspace context</a> on both the server and the client. <code>lds:dataspace-description()</code> returns the current\n                dataspace's description from it, including its <code>rdf:type</code> (<code>lds:EndUserDataspace</code> or <code>lds:AdminDataspace</code>) and, for an\n                end-user dataspace, the <code>lds:admin</code> base URI. Stylesheets receive no other configuration: the service endpoints and credentials are not available to them.</p>\n            <p>Built-in <a href=\"../administration/ontologies/#ontologies\" target=\"_blank\">ontologies</a>, as well as some other system and well-known ontologies, have a local copy in\n                each LinkedDataHub instance. As a result, retrieving their descriptions by dereferencing their URIs using <code>document()</code> does not incur an HTTP request and is much faster. The URI-to-file mapping\n                is defined as Jena's <a href=\"https://jena.apache.org/documentation/io/rdf-input.html#configuring-a-locationmapper\" target=\"_blank\">location mapping</a> and can be found in\n                <a href=\"https://github.com/AtomGraph/LinkedDataHub/blob/develop/src/main/resources/location-mapping.ttl\" target=\"_blank\"><samp>location-mapping.ttl</samp></a> and <a href=\"https://github.com/AtomGraph/LinkedDataHub/blob/develop/src/main/resources/prefix-mapping.ttl\" target=\"_blank\"><samp>prefix-mapping.ttl</samp></a>.</p>\n            <p>Client-side stylesheets use <a href=\"https://www.saxonica.com/saxonjs/documentation3/index.html#!ixsl-extension/instructions/schedule-action\" target=\"_blank\"><code>&lt;ixsl:schedule-action&gt;</code></a> (deprecated) and <a href=\"https://www.saxonica.com/saxonjs/documentation3/index.html#!ixsl-extension/instructions/promise\" target=\"_blank\"><code>&lt;ixsl:promise&gt;</code></a> to load XML documents asynchronously. The metadata required to render forms — constructors, SHACL shapes, and property and object descriptions — is loaded client-side through chains of <code>&lt;ixsl:promise&gt;</code>, so the browser fetches it on demand rather than the server fetching everything up front.</p>\n        </div>\n        <div>\n            <h3 id=\"parameters\">Parameters</h3>\n            <p>Both global (i.e. stylesheet-level) and template parameters are declared using <code>&lt;xsl:param&gt;</code>. LinkedDataHub sets the following global parameters:</p>\n            <table>\n                <caption class=\"ac-vh\">Stylesheet parameters and their types</caption>\n                <thead>\n                    <tr>\n                        <th scope=\"col\">Parameter</th>\n                        <th scope=\"col\">Type</th>\n                        <th scope=\"col\">Description</th>\n                    </tr>\n                </thead>\n                <tbody>\n                    <tr>\n                        <td><code>$lds:origin</code></td>\n                        <td><code>xs:anyURI</code></td>\n                        <td>Origin of the application shell that serves the static assets (the pane-scoped counterpart is the <code>lds:origin()</code> function)</td>\n                    </tr>\n                    <tr>\n                        <td><code>$foaf:Agent</code></td>\n                        <td><code>document-node()?</code></td>\n                        <td>RDF/XML metadata of the authenticated agent (if any)</td>\n                    </tr>\n                    <tr>\n                        <td><code>$acl:agent</code></td>\n                        <td><code>xs:anyURI?</code></td>\n                        <td>URI of the authenticated agent</td>\n                    </tr>\n                    <tr>\n                        <td><code>$ldh:requestUri</code></td>\n                        <td><code>xs:anyURI</code></td>\n                        <td>Full request URI including query string</td>\n                    </tr>\n                    <tr>\n                        <td><code>$ldh:httpHeaders</code></td>\n                        <td><code>map(xs:string, xs:string*)</code></td>\n                        <td>HTTP response headers by name — <code>Content-Language</code>, <code>Link</code>, <code>Memento-Datetime</code> etc. are read from it</td>\n                    </tr>\n                    <tr>\n                        <td><code>$ldh:ajaxRendering</code></td>\n                        <td><code>xs:boolean</code></td>\n                        <td>Whether client-side (Saxon-JS) rendering is enabled</td>\n                    </tr>\n                    <tr>\n                        <td><code>$ldh:renderSystemResources</code></td>\n                        <td><code>xs:boolean</code></td>\n                        <td>Whether system resources are included in the rendering</td>\n                    </tr>\n                    <tr>\n                        <td><code>$ac:contextUri</code></td>\n                        <td><code>xs:anyURI</code></td>\n                        <td>Root deployment URI, against which system endpoints such as <code>oauth2/*</code> are resolved</td>\n                    </tr>\n                    <tr>\n                        <td><code>$ac:uri</code></td>\n                        <td><code>xs:anyURI?</code></td>\n                        <td>URI of the external resource when the request goes through the <a href=\"../http-api/linked-data-proxy/#ld-proxy\">Linked Data proxy</a>; absent for local documents (prefer the <code>ac:uri()</code> function)</td>\n                    </tr>\n                </tbody>\n            </table>\n            <p>Former parameters <code>$ac:mode</code>, <code>$acl:mode</code>, <code>$sd:endpoint</code>, <code>$ac:langs</code> and <code>$lds:Dataspace</code> have been\n                replaced by the functions <code>ac:mode()</code>, <code>acl:mode()</code>, <code>sd:endpoint()</code>, <code>ac:langs()</code> and <code>lds:dataspace()</code> —\n                their values can change per pane or per response, which a global parameter cannot express.</p>\n        </div>\n        <div>\n            <h3 id=\"functions\">Functions</h3>\n            <p>LinkedDataHub and Web-Client provide XSLT functions available to all stylesheets.</p>\n            <h4 id=\"uri-utility-functions\">URI utility functions</h4>\n            <table>\n                <caption class=\"ac-vh\">URI utility functions and what they return</caption>\n                <thead>\n                    <tr>\n                        <th scope=\"col\">Function</th>\n                        <th scope=\"col\">Returns</th>\n                        <th scope=\"col\">Runs on</th>\n                        <th scope=\"col\">Description</th>\n                    </tr>\n                </thead>\n                <tbody>\n                    <tr>\n                        <td><code>ac:absolute-path($href as xs:anyURI)</code></td>\n                        <td><code>xs:anyURI</code></td>\n                        <td>Both</td>\n                        <td>Strips query string and fragment from a URI, returning the path-only form</td>\n                    </tr>\n                    <tr>\n                        <td><code>ac:build-uri(<br></br>  $absolute-path as xs:anyURI?,<br></br>  $query-params as map(xs:string, xs:string*)<br></br>)</code></td>\n                        <td><code>xs:anyURI?</code></td>\n                        <td>Both</td>\n                        <td>Appends a percent-encoded query string built from <code>$query-params</code> to <code>$absolute-path</code></td>\n                    </tr>\n                    <tr>\n                        <td><code>ac:document-uri($uri as item())</code></td>\n                        <td><code>xs:anyURI</code></td>\n                        <td>Both</td>\n                        <td>Strips the fragment identifier from a URI, making it suitable for use with <code>document()</code></td>\n                    </tr>\n                    <tr>\n                        <td><code>ac:fragment-id($uri as xs:anyURI)</code></td>\n                        <td><code>xs:string?</code></td>\n                        <td>Both</td>\n                        <td>Extracts the fragment identifier (the part after <code>#</code>)</td>\n                    </tr>\n                    <tr>\n                        <td><code>ac:uri()</code></td>\n                        <td><code>xs:anyURI?</code></td>\n                        <td>Both</td>\n                        <td>URI of the external resource being viewed through the <a href=\"../http-api/linked-data-proxy/#ld-proxy\">Linked Data proxy</a>; absent for local documents. The server reads it from the <code>$ac:uri</code> parameter, the browser from the <code>uri</code> query parameter</td>\n                    </tr>\n                    <tr>\n                        <td><code>lds:origin()</code></td>\n                        <td><code>xs:anyURI</code></td>\n                        <td>Both</td>\n                        <td>Returns the origin (scheme, host and port) of the current dataspace, e.g. <code>https://localhost:4443/</code>. Used to build absolute URIs for static resources and same-site requests</td>\n                    </tr>\n                    <tr>\n                        <td><code>lds:base()</code></td>\n                        <td><code>xs:anyURI</code></td>\n                        <td>Both</td>\n                        <td>Returns the base URI of the current dataspace</td>\n                    </tr>\n                    <tr>\n                        <td><code>ldh:request-uri()</code></td>\n                        <td><code>xs:anyURI</code></td>\n                        <td>Both</td>\n                        <td>Returns the full request URI including query string</td>\n                    </tr>\n                    <tr>\n                        <td><code>ldh:base-uri($arg as node())</code></td>\n                        <td><code>xs:anyURI</code></td>\n                        <td>Both</td>\n                        <td>Returns the base URI of an XML node; wraps the built-in <code>base-uri()</code></td>\n                    </tr>\n                    <tr>\n                        <td><code>ldh:href($uri as xs:anyURI?)</code></td>\n                        <td><code>xs:anyURI</code></td>\n                        <td>Both</td>\n                        <td>Resolves a URI to a local href, proxying external URIs through the LinkedDataHub proxy. Overloads accept <code>$query-params as map(xs:string, xs:string*)</code> and <code>$fragment as xs:string?</code></td>\n                    </tr>\n                    <tr>\n                        <td><code>ldh:parse-href($href as xs:anyURI)</code></td>\n                        <td><code>map(xs:string, item()?)</code></td>\n                        <td>Both</td>\n                        <td>Inverse of <code>ldh:href()</code> — parses a local href back into its target URI, query parameters and fragment. Shared by the client-side navigation handlers</td>\n                    </tr>\n                    <tr>\n                        <td><code>ldh:query-params()</code></td>\n                        <td><code>map(xs:string, xs:string*)</code></td>\n                        <td>Both</td>\n                        <td>Parses the current request URI's query string into a map of parameter names to values</td>\n                    </tr>\n                    <tr>\n                        <td><code>ldh:build-query($mode as xs:anyURI*)</code></td>\n                        <td><code>map(xs:string, xs:string*)</code></td>\n                        <td>Both</td>\n                        <td>Builds the <code>mode</code> query parameter map that selects the given <a href=\"../user-interface/#layout-modes\">layout mode(s)</a></td>\n                    </tr>\n                    <tr>\n                        <td><code>ldh:parse-query-params($query-string as xs:string)</code></td>\n                        <td><code>map(xs:string, xs:string*)</code></td>\n                        <td>Both</td>\n                        <td>Parses a URL query string into a map of key to value(s)</td>\n                    </tr>\n                    <tr>\n                        <td><code>ldh:url-decode($encoded-string as xs:string)</code></td>\n                        <td><code>xs:string</code></td>\n                        <td>Both</td>\n                        <td>Percent-decodes a URL-encoded string</td>\n                    </tr>\n                </tbody>\n            </table>\n            <h4 id=\"rdf-metadata-functions\">RDF metadata functions</h4>\n            <table>\n                <caption class=\"ac-vh\">RDF metadata functions and what they return</caption>\n                <thead>\n                    <tr>\n                        <th scope=\"col\">Function</th>\n                        <th scope=\"col\">Returns</th>\n                        <th scope=\"col\">Runs on</th>\n                        <th scope=\"col\">Description</th>\n                    </tr>\n                </thead>\n                <tbody>\n                    <tr>\n                        <td><code>ac:label($resource as element())</code></td>\n                        <td><code>xs:string?</code></td>\n                        <td>Both</td>\n                        <td>Extracts a human-readable label from an RDF resource description, trying multiple vocabulary properties</td>\n                    </tr>\n                    <tr>\n                        <td><code>ac:description($resource as element())</code></td>\n                        <td><code>xs:string?</code></td>\n                        <td>Both</td>\n                        <td>Extracts a human-readable description from an RDF resource description</td>\n                    </tr>\n                    <tr>\n                        <td><code>ac:image($resource as element())</code></td>\n                        <td><code>attribute()*</code></td>\n                        <td>Both</td>\n                        <td>Extracts image references (e.g. <code>foaf:depiction</code>, <code>foaf:img</code>) from a resource description</td>\n                    </tr>\n                    <tr>\n                        <td><code>ac:property-label($property as element())</code></td>\n                        <td><code>xs:string?</code></td>\n                        <td>Both</td>\n                        <td>Label of a predicate element, capitalized — resolved by the <code>ac:property-label</code> mode templates. An overload accepts <code>$property-metadata as document-node()</code>, the property descriptions loaded for the current document</td>\n                    </tr>\n                    <tr>\n                        <td><code>ac:object-label($object as node())</code></td>\n                        <td><code>xs:string?</code></td>\n                        <td>Both</td>\n                        <td>Label of a property's object: a resource-valued object is looked up in the current graph, the loaded metadata or its dereferenced document, falling back to the URI's fragment or last path segment; a literal yields its lexical value. An overload accepts <code>$object-metadata as document-node()</code></td>\n                    </tr>\n                    <tr>\n                        <td><code>ac:mode($doc as document-node())</code></td>\n                        <td><code>xs:anyURI</code></td>\n                        <td>Both</td>\n                        <td>The active <a href=\"../user-interface/#layout-modes\">layout mode</a> of the given document. Replaces the former <code>$ac:mode</code> parameter</td>\n                    </tr>\n                    <tr>\n                        <td><code>ac:langs()</code></td>\n                        <td><code>xs:string*</code></td>\n                        <td>Both</td>\n                        <td>The reader's accepted languages, deduplicated to primary subtags and always ending with <samp>en</samp> as a fallback — negotiated server-side, read from <code>navigator.languages</code> in the browser</td>\n                    </tr>\n                    <tr>\n                        <td><code>ac:lang-rank($value as element())</code></td>\n                        <td><code>xs:integer</code></td>\n                        <td>Both</td>\n                        <td>Ranks a property value's language against <code>ac:langs()</code>, so values sort by the reader's preference</td>\n                    </tr>\n                    <tr>\n                        <td><code>ldh:date-time($value as xs:string?)</code></td>\n                        <td><code>xs:dateTime?</code></td>\n                        <td>Both</td>\n                        <td>Parses a lexical value into a <code>xs:dateTime</code> where possible</td>\n                    </tr>\n                    <tr>\n                        <td><code>ldh:datatype-family($datatype as xs:anyURI?)</code></td>\n                        <td><code>xs:string</code></td>\n                        <td>Both</td>\n                        <td>Groups an XSD datatype into a family (numeric, dateTime, string etc.) — drives table column sorting</td>\n                    </tr>\n                    <tr>\n                        <td><code>ldh:sort-key($key as xs:string?, $datatype as xs:anyURI?)</code></td>\n                        <td><code>xs:anyAtomicType?</code></td>\n                        <td>Browser</td>\n                        <td>Converts a lexical value into a typed sort key for its datatype family</td>\n                    </tr>\n                    <tr>\n                        <td><code>ldh:sort-key-lexical($resource as element(), $predicates as xs:anyURI*)</code></td>\n                        <td><code>xs:string?</code></td>\n                        <td>Browser</td>\n                        <td>The lexical sort key of a resource: coalesces across <code>$predicates</code> in order, preferring values whose language matches the reader's first accepted language. Feeds <code>ldh:sort-key()</code></td>\n                    </tr>\n                    <tr>\n                        <td><code>ldh:sort-datatype($resources as element()*, $predicates as xs:anyURI*)</code></td>\n                        <td><code>xs:anyURI?</code></td>\n                        <td>Browser</td>\n                        <td>The datatype shared by a sort column's literals; absent when the column mixes datatypes or carries plain literals or resources. Keys the typed re-sort that keeps a view block's client-side order agreeing with its SPARQL <code>ORDER BY</code></td>\n                    </tr>\n                </tbody>\n            </table>\n            <h4 id=\"http-and-sparql-functions\">HTTP and SPARQL functions</h4>\n            <table>\n                <caption class=\"ac-vh\">HTTP and SPARQL functions and what they return</caption>\n                <thead>\n                    <tr>\n                        <th scope=\"col\">Function</th>\n                        <th scope=\"col\">Returns</th>\n                        <th scope=\"col\">Runs on</th>\n                        <th scope=\"col\">Description</th>\n                    </tr>\n                </thead>\n                <tbody>\n                    <tr>\n                        <td><code>ldh:query-result($endpoint as xs:anyURI, $query as xs:string)</code></td>\n                        <td><code>document-node()?</code></td>\n                        <td>Both</td>\n                        <td>Runs <code>$query</code> against <code>$endpoint</code> over the SPARQL Protocol and returns the response: RDF/XML for <code>CONSTRUCT</code> and <code>DESCRIBE</code>, SPARQL Results XML for <code>SELECT</code> and <code>ASK</code>. Call it from any stylesheet: each engine has its own implementation. Server-side, it <code>POST</code>s the query as <code>application/sparql-query</code> through <code>ldh:send-request()</code>, so a long query does not hit a URL length limit; the result is empty when the response has no body. Client-side, it sends a <code>GET</code> and loads the response with <code>document()</code>. An endpoint on another origin is fetched through the Linked Data proxy (<code>?uri=</code>). <code>document()</code> is synchronous, so the page waits for the response. SaxonJS also keeps the document for the rest of the page session, so a repeated query does not reach the network. A failed request raises a dynamic error, so wrap the call in <code>xsl:try</code> when the endpoint may be unavailable. Example: <code>ldh:query-result(sd:endpoint(), 'DESCRIBE &lt;' || @rdf:about || '&gt;')</code></td>\n                    </tr>\n                    <tr>\n                        <td><code>ldh:send-request(<br></br>  $href as xs:anyURI,<br></br>  $method as xs:string,<br></br>  $media-type as xs:string?,<br></br>  $body as item()?,<br></br>  $headers as map(xs:string, xs:string*)<br></br>)</code></td>\n                        <td><code>document-node()?</code></td>\n                        <td>Server</td>\n                        <td>Sends an HTTP request with any <code>$method</code> and parses the response body as XML; returns an empty sequence when the response has no body. A body is sent only when both <code>$media-type</code> and <code>$body</code> are given, and <code>$body</code> is sent as its string value, so serialize a node before passing it. <code>$headers</code> maps a header name to its value, of which only the first is sent; pass <code>map{}</code> for none. A response status outside 2xx, a timeout or an unparseable body raises a dynamic error that <code>xsl:try</code> can catch. Server-side only: it is the <code>SendHTTPRequest</code> Java extension function and has no browser declaration, so calling it from a stylesheet that also runs in the browser fails to compile. Guard such a call with <code>use-when=\"system-property('xsl:product-name') = 'SAXON'\"</code>; for a SPARQL query, call <code>ldh:query-result()</code> instead, which works on both sides. In the browser, <code>ixsl:http-request()</code> is the asynchronous counterpart. Example: <code>ldh:send-request($href, 'GET', (), (), map{ 'Accept': 'application/rdf+xml' })</code></td>\n                    </tr>\n                    <tr>\n                        <td><code>ldh:link-targets($link-headers as xs:string*, $marker as xs:string)</code></td>\n                        <td><code>xs:anyURI*</code></td>\n                        <td>Both</td>\n                        <td>Extracts the target URIs of the <code>Link</code> response header entries, across all <code>Link</code> header values, whose parameters contain <code>$marker</code> (e.g. a <code>rel</code> value) — on the server, <code>acl:mode()</code> and <code>ldh:timemap()</code> read the response's <code>Link</code> header through it; in the browser, it reads each response's <code>Link</code> header into the values that <code>acl:mode()</code>, <code>sd:endpoint()</code> and <code>ldh:timemap()</code> return</td>\n                    </tr>\n                    <tr>\n                        <td><code>ldh:reserialize($doc as document-node())</code></td>\n                        <td><code>document-node()</code></td>\n                        <td>Both</td>\n                        <td>Round-trips a document through serialization, normalizing it</td>\n                    </tr>\n                </tbody>\n            </table>\n            <h4 id=\"dataspace-and-access-functions\">Dataspace and access functions</h4>\n            <table>\n                <caption class=\"ac-vh\">Dataspace and access functions and what they return</caption>\n                <thead>\n                    <tr>\n                        <th scope=\"col\">Function</th>\n                        <th scope=\"col\">Returns</th>\n                        <th scope=\"col\">Runs on</th>\n                        <th scope=\"col\">Description</th>\n                    </tr>\n                </thead>\n                <tbody>\n                    <tr>\n                        <td><code>sd:endpoint()</code></td>\n                        <td><code>xs:anyURI</code></td>\n                        <td>Both</td>\n                        <td>SPARQL endpoint of the current data pane — the local endpoint, or the remote dataspace's when browsing another dataspace through the <a href=\"../http-api/linked-data-proxy/#ld-proxy\">proxy</a>. Replaces the former <code>$sd:endpoint</code> parameter</td>\n                    </tr>\n                    <tr>\n                        <td><code>lds:context()</code></td>\n                        <td><code>document-node()?</code></td>\n                        <td>Both</td>\n                        <td>RDF/XML description of the instance's dataspaces, read from the <a href=\"../dataspace/#context\">dataspace context</a>; absent if it cannot be loaded. Replaces the former <code>$lds:Context</code> parameter</td>\n                    </tr>\n                    <tr>\n                        <td><code>lds:dataspace-description()</code></td>\n                        <td><code>element()*</code></td>\n                        <td>Both</td>\n                        <td>Description of the current dataspace, looked up in <code>lds:context()</code> by origin</td>\n                    </tr>\n                    <tr>\n                        <td><code>lds:dataspace()</code></td>\n                        <td><code>xs:anyURI?</code></td>\n                        <td>Browser</td>\n                        <td>URI of the dataspace resource describing the current dataspace. Replaces the former <code>$lds:Dataspace</code> parameter (its description is returned by <code>lds:dataspace-description()</code>)</td>\n                    </tr>\n                    <tr>\n                        <td><code>acl:mode()</code></td>\n                        <td><code>xs:anyURI*</code></td>\n                        <td>Both</td>\n                        <td>Access modes granted on the current document, read from the response's <code>Link</code> headers. Replaces the former <code>$acl:mode</code> parameter</td>\n                    </tr>\n                </tbody>\n            </table>\n            <h4 id=\"versioning-functions\">Versioning functions</h4>\n            <table>\n                <caption class=\"ac-vh\">Versioning functions and what they return</caption>\n                <thead>\n                    <tr>\n                        <th scope=\"col\">Function</th>\n                        <th scope=\"col\">Returns</th>\n                        <th scope=\"col\">Runs on</th>\n                        <th scope=\"col\">Description</th>\n                    </tr>\n                </thead>\n                <tbody>\n                    <tr>\n                        <td><code>ldh:memento-datetime()</code></td>\n                        <td><code>xs:string?</code></td>\n                        <td>Both</td>\n                        <td>The <code>Memento-Datetime</code> of the currently viewed <a href=\"../versioning/#snapshots\">historical version</a>, absent on the live document</td>\n                    </tr>\n                    <tr>\n                        <td><code>ldh:timemap()</code></td>\n                        <td><code>xs:anyURI?</code></td>\n                        <td>Both</td>\n                        <td>The document's <a href=\"../versioning/#timemap\">TimeMap</a> URI from the <code>Link</code> response header; absent when the document is not versioned</td>\n                    </tr>\n                </tbody>\n            </table>\n            <h4 id=\"utility-functions\">Utility functions</h4>\n            <table>\n                <caption class=\"ac-vh\">Utility functions and what they return</caption>\n                <thead>\n                    <tr>\n                        <th scope=\"col\">Function</th>\n                        <th scope=\"col\">Returns</th>\n                        <th scope=\"col\">Runs on</th>\n                        <th scope=\"col\">Description</th>\n                    </tr>\n                </thead>\n                <tbody>\n                    <tr>\n                        <td><code>ac:uuid()</code></td>\n                        <td><code>xs:string</code></td>\n                        <td>Both</td>\n                        <td>Generates a random UUID</td>\n                    </tr>\n                    <tr>\n                        <td><code>ldh:hash-code($string as xs:string)</code></td>\n                        <td><code>xs:integer</code></td>\n                        <td>Browser</td>\n                        <td>Deterministic 32-bit djb2 hash of a string's codepoints — the counterpart to <code>ac:uuid()</code> for identifiers that must survive a reload because they are re-derived rather than stored</td>\n                    </tr>\n                </tbody>\n            </table>\n            <p>The many remaining <code>ac:</code> and <code>ldh:</code> functions are internal machinery, not a stable API, and are deliberately not documented\n                here: the client-side <code>render-*</code>, <code>load-*</code>, <code>set-*</code>, <code>*-response</code> and <code>*-thunk</code> families\n                together with the promise, progress, cursor and DOM helpers they call; the constructor, form and SPARQL-manipulation helpers behind the editing\n                UI; and Web-Client functions that LinkedDataHub has superseded, such as <code>ac:construct()</code> and the SVG rendering helpers.</p>\n        </div>\n    </div>\n    <div>\n        <h2 id=\"other-assets\">Other assets</h2>\n        <div>\n            <h3 id=\"css\">CSS</h3>\n            <p>The stylesheet links are emitted by the <code>ac:Stylesheets</code> XSLT template mode, in cascade order: the vendored design-system stylesheets — <samp>fonts.css</samp>, <samp>colors_and_type.css</samp> (tokens), <samp>app.css</samp> (components; it imports <samp>core.css</samp>, which imports <samp>controls.css</samp> and <samp>overlays.css</samp>) and <samp>retro.css</samp> (the skin) — then <samp>ldh.css</samp>, LinkedDataHub's one app layer over the kits, loaded last so it wins the ties it is written to win. Feature-specific stylesheets are linked ahead of them and only when needed: <samp>rdfa-editor.css</samp> for rich-text editing when an agent is authenticated, <samp>yasqe.css</samp> for the SPARQL editor. Dataspace stylesheets that import <samp>layout.xsl</samp> can override the <code>ac:Stylesheets</code> template mode to add or replace stylesheets.</p>\n            <p>Components are named by class rather than by element: <code>ac-*</code> for the design system's own components (<samp>ac-btn</samp>, <samp>ac-alert</samp>, <samp>ac-card</samp>, <samp>ac-badge</samp>) and <code>ldh-*</code> for the ones LinkedDataHub adds over them (<samp>ldh-block</samp>, <samp>ldh-actionbar</samp>, <samp>ldh-address</samp>). A component is varied by stacking one class from each axis onto it, not by a compound name — the action bar's <dfn>Actions</dfn> button is <samp>ac-btn in-neutral ap-outline sz-md</samp>, a form's <dfn>Save</dfn> button <samp>ac-btn in-primary ap-solid sz-md</samp>.</p>\n            <table>\n                <caption class=\"ac-vh\">Class axes that vary a component</caption>\n                <thead>\n                    <tr>\n                        <th scope=\"col\">Axis</th>\n                        <th scope=\"col\">Classes</th>\n                    </tr>\n                </thead>\n                <tbody>\n                    <tr>\n                        <td>Intent</td>\n                        <td><samp>in-primary</samp>, <samp>in-neutral</samp>, <samp>in-accent</samp>, <samp>in-destructive</samp>, <samp>in-negative</samp>, <samp>in-inverse</samp></td>\n                    </tr>\n                    <tr>\n                        <td>Appearance</td>\n                        <td><samp>ap-solid</samp>, <samp>ap-outline</samp>, <samp>ap-ghost</samp>, <samp>ap-fixed</samp></td>\n                    </tr>\n                    <tr>\n                        <td>Size</td>\n                        <td><samp>sz-xs</samp>, <samp>sz-sm</samp>, <samp>sz-md</samp>, <samp>sz-lg</samp>, <samp>sz-xl</samp></td>\n                    </tr>\n                    <tr>\n                        <td>Variant</td>\n                        <td><samp>va-informative</samp>, <samp>va-positive</samp>, <samp>va-negative</samp>, <samp>va-neutral</samp>, <samp>va-emphasis</samp>, <samp>va-enclosed</samp>, <samp>va-line</samp>, <samp>va-hero</samp>, <samp>va-inverse</samp>, <samp>va-fixed</samp> — carried by components that vary by kind rather than by intent, such as <samp>ac-alert</samp></td>\n                    </tr>\n                </tbody>\n            </table>\n            <p>That vocabulary is the contract the templates emit, so restyling is a matter of writing rules against those classes. Changes belong in a stylesheet of the dataspace's own: <samp>ldh.css</samp> is the platform's app layer and is replaced wholesale on upgrade. Override the <code>ac:Stylesheets</code> template mode and call <code>xsl:next-match</code> first, which emits the platform's links and leaves yours last in the cascade, where they win the ties they need to win. Omitting <code>xsl:next-match</code> drops the vendored kits along with <samp>ldh.css</samp> and leaves the components unstyled.</p>\n        </div>\n        <div>\n            <h3 id=\"javascript\">JavaScript</h3>\n            <p>The script links are emitted by the <code>xhtml:Script</code> XSLT template mode. It loads <samp>functions.js</samp>, the Saxon-JS 3 runtime together with the compiled client stylesheet (when client-side rendering is enabled), and feature-specific libraries: the YASQE SPARQL editor, the SPARQL builder, OpenLayers for maps, Google Charts for charts, and three.js with 3d-force-graph for the 3D graph mode.</p>\n            <p>LinkedDataHub only uses JavaScript for the functionality that cannot be achieved using client-side XSLT.</p>\n        </div>\n    </div>\n    <p class=\"ldh-body-lg\">To customize the built-in stylesheets, follow the <a href=\"../../extending/change-layout/\">Change layout</a> and <a href=\"../../extending/build-apps/\">Build apps</a> guides</p>\n</div>"^^<http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral> .
