@use "/shell" as *; @use "quark:list" as list; #release-notice { /* opens once: sheet re-runs restart a delay, so gate it on the fact it writes */ &:not([data-did-open]) { @delay 7000 { is-open: ""; data-did-open: ""; } } /* prevent clicks from bubbling to the sheet */ @on mouseup, click (stop-propagation); } provider-fetch[api-url*="package-metas/index.json"][is-success] { $package-indices: prop("provision").body; /* `excom.navGroup` moves a package out of its type's list, into that group */ $ungrouped: list.reject($package-indices.packages, "navGroup"); .package-links { [bind-elements] ul:not(ul ul) { content: iterate(getPackagesByType($ungrouped, "kit-element")); } [bind-element-bases] ul:not(ul ul) { content: iterate(getPackagesByType($ungrouped, "element-base")); } [bind-tools] ul:not(ul ul) { content: iterate(getPackagesByType($ungrouped, "tool")); } /* the standalone libraries: same rows, rendered flat (shell.css) */ [bind-libraries] ul:not(ul ul) { content: iterate(getPackagesByType($ungrouped, "library")); } [bind-library-group] ul:not(ul ul) { content: iterate(list.filter($package-indices.packages, "navGroup", "libraries")); } ul:not(ul ul) > li { $pkg: item.shortName; > spa-a { route-href: "/packages/#{item.shortName}"; } } /* one `content` rule per link: a second one would rewrite the first's text on every pass */ ul:not(ul ul, [bind-libraries] ul) > li > spa-a { content: item.shortName; } [bind-libraries] ul:not(ul ul) > li > spa-a { content: displayName(item.shortName); } /* packages whose docs span several pages: one collapsible group per section */ [bind-sections] { content: iterate(item.docSections); summary { content: item.title; } details > ul { content: iterate(item.docs); spa-a { route-href: "/packages/#{$pkg}/#{item.name}"; content: item.title; } } details:not(:has(spa-a[is-active])) { open: none; } } } /* page titles: the page, then the site. The docs home keeps the title in the document head; the other routes carry theirs in markup */ spa-route[is-active] { /* a site guide */ &[route-href$=":name"] { $title-guide: list.find($package-indices.docs, "name", $route.params.name); document-title: "#{$title-guide.title or $route.params.name} · Nucleus · docs"; } /* a package README */ &[route-href$=":packageName"] { document-title: "#{displayName($route.params.packageName)} · Nucleus · docs"; } /* one page of a package's docs */ &[route-href$=":docName"] { $title-package: list.find($package-indices.packages, "shortName", $route.params.packageName); document-title: "#{docTitle($title-package, $route.params.docName)} · #{displayName($route.params.packageName)} · Nucleus · docs"; } } /* the page's markdown file, for the footer link: the docs home and each guide the index lists, and a package's page whose index entry says `markdown` (build-docs-index sets it; the dev server's index has none, so no link there). siteDocHref and the path check say which URL is the page's own: the 404 and a package's doc pages have none */ > spa-manager[active-url] { $page-path: attr("active-url").split("#").at(0).split("?").at(0); $page-name: if($page-path == SITE_HOME: SITE_HOME_DOC; else: $page-path.split("/").at(-1)); $page-guide: list.find($package-indices.docs, "name", $page-name); $page-package: list.find($package-indices.packages, "shortName", $page-name); $page-markdown: if($page-guide and siteDocHref($page-guide.name) == $page-path: "/docs/#{$page-guide.name}.md"; $page-package.markdown and "#{SITE_BASE}/packages/#{$page-package.shortName}" == $page-path: "/#{$page-package.shortName}.md"); footer [bind-page-markdown] { href: $page-markdown; content: ternary($page-markdown, "Markdown version of this page"); } } } spa-route { $route: prop("provision"); /* paramless routes name their guide in markup (the docs home, `/`); /docs/:name gets it from params */ $route-doc-name: attr("data-doc-name"); } /* the desktop aside and the mobile sheet stamp the same nav template */ [data-site-nav] { details:has(spa-a[is-active]) { /* not kosher */ open: ""; } spa-a[is-active] { aria-current: ""; } spa-a:not([is-active]) { aria-current: none; } } /* mobile sheet: Escape / back gesture while open; a tapped link closes it */ #site-menu { &[is-open] dismiss-watcher { is-active: ""; } &:not([is-open]) dismiss-watcher { is-active: none; } @on click (target: "spa-a") { is-open: none; } } #site-menu-gesture { &:has(> #site-menu[is-open]) { progress-offset: 1; } &:not(:has(> #site-menu[is-open])) { progress-offset: 0; } @on gesture-handler-start { #site-menu { is-scrubbing: ""; } } @on gesture-handler-end { #site-menu { is-open: event.detail.snap == 1; is-scrubbing: none; } } } main { @on copy-source (handle: copySource); } #search-dialog[open] { > include-content { is-active: ""; /* for some reason this is necessary on first render */ @on include-content-did-render (handle: focusInput); } input[type="search"] { /* works on all subsequent opens */ autofocus: ""; } } #search-dialog:not([open]) input[type="search"] { autofocus: none; }

Diving Deeper

This section is for technically curious deep-divers. It explains why the Nucleus Stack/ASO is shaped as it is, names the ideas it stands on, and is candid about what it forgoes.

Reading order

  1. Origin Story — why Quark exists, and the platform gap it fills.
  2. Adapter, State, Orchestrator — the pattern, defined precisely.
  3. Prior Art — where the ideas overlap and descend from existing ones, and what ASO is not.
  4. Limitations — the edges, the divergences, and the unresolved bits of this implementation
  5. Glossary — every term - one definition each.

Design principles

HTML is primary; JavaScript is a guest. A conventional stack puts a JavaScript memory model in charge and targets the document as its compiled output. ASO upends that. The document is the program's state, elements embed into it, and optional scripting is invited in as pure functions once rules run out of expressiveness.

The unified surface. What the application reads and what it presents are the same artifact. Other frameworks' pipelines — memory model, logic, render, DOM — is exactly the severing of that unity, and everything required afterward (hydration, effects, reconciliation) exists to repair it. ASO never severs it.

Distinctions are drawn by ownership, not by data. Whether a value is a primitive attribute or a rich object is a storage detail of the host platform. Architecturally, what matters is who may write it: the author, the element that owns it, or the Orchestrator.

Single responsibility is a constraint, not a preference. An element with two jobs must be two elements. That is what makes composition work w/o a component model.

There are no components. Elements have no intrinsic knowledge of any other elements outside of their own family. Reusable UI is a view — markup plus its own CSS and Orchestrator sheet — loaded where needed. Nothing that ships with the stack decides what your page looks like.

Coordination is anonymous and addressed by location. Rules name places in the document with selectors. No participant holds a reference to another; none calls another. That is what lets two sheets cooperate without knowing the other exists. This follows CSS and the Blackboard pattern.

State describes only the present. No logic, no history, no futures. Animation belongs to CSS.

Failure is inert. A broken expression logs and does nothing. Malfunction in the Orchestrator degrades the experience; it cannot corrupt the state.

The platform is the framework. Selectors, mutation observers, custom elements, events, custom properties, view transitions. The stack adds a language - which is simply a derivative of CSS - and an optional factory over those primitives.

One paragraph per role

An Adapter is a located element — or a family of elements — that bridges the State and a foreign protocol: a system (network, storage, sensors, the clock, history, the viewport) or a person (pointer, keyboard, focus, the accessibility tree). It carries the protocol's state as attributes and provisions on itself, its occurrences as events, and its non-State machinery privately.

State is an application's living, structured, declarative body of data — the single source of truth - that is simultaneously what the application reads and presents.

The Orchestrator is a declarative, selector-driven observer that watches State changes and writes coordinated changes back to it, holding no separate state of its own.

Continue to Adapter, State, Orchestrator.

Beta. The Nucleus Stack is in beta for a few weeks until features are stabilized and optimized.

Thanks — we'll email you when it ships.

Something went wrong. Please try again.