qualifier 0.6.1

Deterministic quality annotations for software artifacts
Documentation
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>{{ title }}{% if title !== site.title %} — {{ site.title }}{% endif %}</title>
    <meta name="description" content="{{ description or site.description }}" />
    <script>
      (function () {
        // Theme init — sets data-theme/data-theme-pref synchronously
        // before paint to avoid a wrong-theme flash.
        try {
          var pref = localStorage.getItem("qualifier-theme") || "system";
          var resolved = pref;
          if (pref === "system") {
            resolved = window.matchMedia("(prefers-color-scheme: light)").matches ? "light" : "dark";
          }
          document.documentElement.dataset.themePref = pref;
          document.documentElement.dataset.theme = resolved;
        } catch (e) {
          document.documentElement.dataset.themePref = "system";
          document.documentElement.dataset.theme = "dark";
        }

        // Font load coordination — block the body's first paint until
        // every preloaded weight has resolved (loaded or, with
        // font-display: optional, committed to fallback). Without this
        // each weight transitions independently and produces multi-stage
        // FOUT/FOIT on slow connections.
        var html = document.documentElement;
        html.classList.add("fonts-loading");

        function done() {
          html.classList.remove("fonts-loading");
          html.classList.add("fonts-loaded");
        }

        // Hard ceiling: never hide the page longer than 1500ms even if
        // the Font Loading API never resolves (very slow 2G, broken
        // network). Above that, fallback is better than blank.
        if (document.fonts && document.fonts.ready) {
          var timeout = new Promise(function (r) { setTimeout(r, 1500); });
          Promise.race([document.fonts.ready, timeout]).then(done);
        } else {
          done();
        }
      })();
    </script>
    <link rel="preload" href="/fonts/instrument-sans.woff2" as="font" type="font/woff2" crossorigin />
    <link rel="preload" href="/fonts/atkinson-regular.woff2" as="font" type="font/woff2" crossorigin />
    <link rel="preload" href="/fonts/jetbrains-mono.woff2" as="font" type="font/woff2" crossorigin />
    <link rel="stylesheet" href="/css/style.css" />
    {% if nav == "home" %}
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@xterm/xterm@5/css/xterm.min.css" />
    <script src="https://cdn.jsdelivr.net/npm/@xterm/xterm@5/lib/xterm.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@xterm/addon-fit@0/lib/addon-fit.min.js"></script>
    <script src="/wasm/qualifier.js"></script>
    <link rel="stylesheet" href="/css/playground.css" />
    {% endif %}
  </head>
  <body>
    <nav class="site-nav">
      <div class="site-nav-inner">
        <a href="/" class="nav-logo">Qualifier</a>
        <div class="nav-right">
          <div class="nav-links">
            <a href="/format/"{% if nav == "format" %} aria-current="page"{% endif %}>Format</a>
            <a href="/metabox/"{% if nav == "metabox" %} aria-current="page"{% endif %}>Metabox</a>
            <a href="/cli/"{% if nav == "cli" %} aria-current="page"{% endif %}>CLI</a>
            <a href="{{ site.repo }}" class="nav-github">GitHub</a>
          </div>
          <button class="theme-toggle" type="button" aria-label="Cycle color theme" title="Cycle theme: system / dark / light">
            <svg class="icon-system icon-system-desktop" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
              <rect x="2" y="3" width="12" height="8.5" rx="0.5"/>
              <line x1="6" y1="14" x2="10" y2="14"/>
              <line x1="8" y1="11.5" x2="8" y2="14"/>
            </svg>
            <svg class="icon-system icon-system-mobile" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
              <rect x="4" y="1.5" width="8" height="13" rx="1"/>
              <line x1="7" y1="12.5" x2="9" y2="12.5"/>
            </svg>
            <svg class="icon-dark" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
              <path d="M13 9.5 A6 6 0 1 1 6.5 3 A4.5 4.5 0 0 0 13 9.5 Z"/>
            </svg>
            <svg class="icon-light" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
              <circle cx="8" cy="8" r="3"/>
              <line x1="8" y1="1.5" x2="8" y2="3"/>
              <line x1="8" y1="13" x2="8" y2="14.5"/>
              <line x1="1.5" y1="8" x2="3" y2="8"/>
              <line x1="13" y1="8" x2="14.5" y2="8"/>
              <line x1="3.4" y1="3.4" x2="4.5" y2="4.5"/>
              <line x1="11.5" y1="11.5" x2="12.6" y2="12.6"/>
              <line x1="3.4" y1="12.6" x2="4.5" y2="11.5"/>
              <line x1="11.5" y1="4.5" x2="12.6" y2="3.4"/>
            </svg>
          </button>
          <button class="nav-menu-btn" type="button" aria-label="Toggle menu"></button>
        </div>
      </div>
    </nav>

    <main>{% if prose %}<div class="prose">{{ content | safe }}</div>{% else %}{{ content | safe }}{% endif %}</main>

    <footer class="site-footer">
      <p>
        &copy; 2026 Empathic, Inc. &middot;
        <a href="{{ site.repo }}">GitHub</a> &middot;
        <a href="https://docs.rs/qualifier">docs.rs</a> &middot;
        <a href="https://crates.io/crates/qualifier">crates.io</a>
      </p>
    </footer>
    <script>
      (function () {
        var ORDER = ["system", "dark", "light"];
        var btn = document.querySelector(".theme-toggle");
        var menuBtn = document.querySelector(".nav-menu-btn");

        function applyPref(pref) {
          var resolved = pref;
          if (pref === "system") {
            resolved = window.matchMedia("(prefers-color-scheme: light)").matches ? "light" : "dark";
          }
          document.documentElement.dataset.themePref = pref;
          document.documentElement.dataset.theme = resolved;
          try { localStorage.setItem("qualifier-theme", pref); } catch (e) {}
          window.dispatchEvent(new CustomEvent("qualifier:theme-change", { detail: { pref: pref, theme: resolved } }));
        }

        if (btn) {
          btn.addEventListener("click", function () {
            var current = document.documentElement.dataset.themePref || "system";
            var next = ORDER[(ORDER.indexOf(current) + 1) % ORDER.length];
            applyPref(next);
          });
        }

        // Live-follow system changes when in "system" mode
        var mql = window.matchMedia("(prefers-color-scheme: light)");
        mql.addEventListener("change", function () {
          if ((document.documentElement.dataset.themePref || "system") === "system") {
            applyPref("system");
          }
        });

        if (menuBtn) {
          menuBtn.addEventListener("click", function () {
            var nav = document.querySelector(".site-nav");
            if (nav.hasAttribute("data-menu-open")) nav.removeAttribute("data-menu-open");
            else nav.setAttribute("data-menu-open", "");
          });
        }
      })();
    </script>
  </body>
</html>