@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; }

nucleus-quark-highlighter

Quark sheets and Nucleus-style HTML, highlighted and formatted in VS Code / Cursor — the same grammar that colors every code block on this site.

The Nucleus & Quark Syntax Highlighter extension adds a Quark language for .quark files, highlights Quark inside <quark-sheet> in HTML, and gives custom elements and dashed attributes their own color so Adapters and their state stand apart from native markup. Tags, custom tags, attributes and custom attributes share one palette in both grammars, so a sheet and the markup it orchestrates read the same way.

<section>
  <provider-fetch api-url="/api/todos">
    <ul><template><li></li></template></ul>
  </provider-fetch>
  <quark-sheet>
    provider-fetch[is-success] {
      $todos: prop("provision").body;
      ul { content: iterate($todos); }
      li { content: item.title; }
    }
  </quark-sheet>
</section>

Features

  • Quark language .quark files with CSS-familiar highlighting, folding, bracket matching and /* */ comments; Quark's at-rules — @use, @scope, @on with its event list, @dispatch / @command, @view-transition, @delay, @warn / @debug / @error — color their names, options groups, durations, messages and blocks
  • Quark's language, nothing else An at-rule Quark does not have, such as @media or @keyframes, is colored as an error, because Quark's parser rejects it
  • Inline sheets Quark inside <quark-sheet> in HTML is highlighted as Quark
  • Custom elements stand out Dashed tags / dashed attributes get their own color in HTML and in Quark selectors; a dashed tag keeps that color wherever it appears in a selector — attribute-qualified, inside :is() / :not() / :has(), or before a pseudo-class or pseudo-element
  • Format Document .quark files format with @excom/quark-formatter (Shift+Alt+F)
  • Format inline sheets Quark: Format <quark-sheet> blocks formats every sheet in the open HTML file
  • File icon .quark files carry the Quark icon in the explorer and tabs
  • Shiki grammar @excom/nucleus-quark-highlighter/shiki highlights Quark / Nucleus HTML in docs and static sites

Installation

Install Nucleus & Quark Syntax Highlighter from the editor's Extensions view, or from the registries directly:

  • VS Code — Visual Studio Marketplace, or ext install excom.nucleus-quark-highlighter in Quick Open
  • Cursor / VSCodium / Windsurf — these editors do not read the Marketplace; install the .vsix by hand (below)

To install a build by hand, download nucleus-quark-highlighter-<version>.vsix from the GitHub releases and run code --install-extension <file> (cursor --install-extension in Cursor).

For docs sites and build tooling the grammar is also on npm:

npm install @excom/nucleus-quark-highlighter

Usage

Open a .quark file and the language mode is Quark. Open any HTML file and <quark-sheet> bodies, custom elements and dashed attributes are colored without further setup.

Formatting

  • .quark files — Format Document (Shift+Alt+F, or format-on-save) reformats the whole file
  • Inline sheets in HTML — run Quark: Format <quark-sheet> blocks from the Command Palette; every sheet body in the active file is formatted and re-indented one level past its tag

Inline sheets need the command because VS Code's HTML formatter only formats the <style> / <script> bodies it knows about and offers no hook for custom tags. A sheet that does not parse is left untouched and the reason appears in the status bar.

Shortcuts

Cmd+/ (Ctrl+/) and Shift+Alt+A both toggle /* */ comments. Quark's comments are CSS's own, so there are no // line comments.

Highlighting with Shiki

The extension's TextMate grammars are exported for Shiki:

import { createHighlighter } from "shiki";
import { shikiLangs } from "@excom/nucleus-quark-highlighter/shiki";
​
const highlighter = await createHighlighter({
  themes: ["github-light", "github-dark"],
  langs: ["html", "css", ...shikiLangs],
});
​
highlighter.codeToHtml(source, { lang: "quark", theme: "github-dark" });

quark highlights standalone sheets. html-custom-elements is an injection: once registered, every html block gets custom-element / dashed-attribute coloring and Quark highlighting inside <quark-sheet>. Load css alongside them; the Quark grammar embeds it.

Release notes (2)

0.1.5

  • Fix highlighting after a bare word directly before a closing bracket, as in if($a: 1; else: preserve): the rest of the sheet was coloured as one value. Remove the /// documentation comment rule: Quark has only /* … */ comments, so a /// line is no longer coloured as one in the editor

0.1.1

  • Ship only dist (and declared extras) in the npm tarball; drop build logs, tests and sources
  • Fix vsix packaging (the npm files allowlist replaces .vscodeignore), ship the MIT license text, and publish the extension to the Visual Studio Marketplace and Open VSX from CI with the vsix attached to a GitHub release
View Source

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.