// The Jarl logo and the login page's wordmark, drawn as inline SVG so they // appear together with the page instead of loading afterwards. // // The "JARL" wordmark: angular Norse-style letters drawn as paths (no font // needed). The login page shows it over a rule with DNS nodes; the header // shows the letters alone. The letters use the text color and the rule the // accent color, so it follows the theme. import * as logoData from "./logo.js"; const NS = "http://www.w3.org/2000/svg"; function el(tag, attrs, ...children) { const e = document.createElementNS(NS, tag); for (const [k, v] of Object.entries(attrs || {})) e.setAttribute(k, v); for (const c of children) e.append(c instanceof Node ? c : document.createTextNode(c)); return e; } // Letters on a 100-unit cap height; counters are cut with evenodd. const letters = [ // J: a heavy stem whose foot hooks back into a barb { x: 0, d: "M14 0 H48 V10 H42 V80 L31 100 H5 L0 93 L19 84 H24 V10 H14 Z" }, // A: peaked top, flaring legs, a diamond for a counter { x: 60, d: "M35 0 L46 10 L64 90 L70 100 H50 L44 76 L35 62 L26 76 L20 100 H0 L6 90 L24 10 Z M35 26 L41 40 L35 54 L29 40 Z" }, // R: squared bowl with cut corners, a long kicked leg { x: 142, d: "M0 0 H48 L60 12 V40 L50 50 L66 100 H46 L34 60 H18 V100 H0 Z M18 14 H41 L46 19 V35 L41 46 H18 Z" }, // L: the base ends in an upswept spike { x: 220, d: "M0 0 H18 V84 H40 L58 70 L54 100 H0 Z" }, ]; // wordmark returns the login page's wordmark, letters over the rule. // wordmark({ rule: false, height: 19, cls: "brand-name" }) returns just the // letters, height pixels tall. export function wordmark({ rule = true, height, cls = "wordmark" } = {}) { const letterG = el("g", { fill: "currentColor", "fill-rule": "evenodd" }, ...letters.map((l) => el("path", { d: l.d, transform: `translate(${l.x} 0)` }))); if (!rule) { const attrs = { class: cls, viewBox: "-2 -2 282 104", role: "img", "aria-label": "Jarl" }; if (height) Object.assign(attrs, { height, width: Math.round(height * 282 / 104) }); return el("svg", attrs, el("title", null, "Jarl"), letterG); } // The rule: tapered lines, two nodes and a "DNS" node in the middle. const ruleG = el("g", { class: "wordmark-rule", transform: "translate(0 118)" }, el("path", { d: "M2 18 L98 15.6 V20.4 Z M278 18 L182 15.6 V20.4 Z", class: "fill" }), el("circle", { cx: 106, cy: 18, r: 4.6, class: "line" }), el("path", { d: "M110.6 18 H122 M158 18 H169.4", class: "line" }), el("circle", { cx: 140, cy: 18, r: 17, class: "line" }), el("circle", { cx: 174, cy: 18, r: 4.6, class: "line" }), el("text", { x: 140, y: 22.5, "text-anchor": "middle", class: "dns" }, "DNS")); return el("svg", { class: cls, viewBox: "-4 -4 288 162", role: "img", "aria-label": "Jarl" }, el("title", null, "Jarl"), letterG, ruleG); } // logo returns the Jarl logo (traced from artwork/logo.png by // scripts/logo.py) as an SVG of the given size in pixels. export function logo(size, cls) { return el("svg", { class: cls || "logo", width: size, height: size, viewBox: logoData.viewBox, "aria-hidden": "true", focusable: "false" }, el("g", { transform: logoData.transform }, ...logoData.layers.map(([fill, d]) => el("path", { fill, d })))); }