Web UI: Jarl logo and wordmark
Add the logo, a Viking jarl drawn like a woodcut whose spear-pointed crown holds a DNS tree. It is generated by scripts/logo.py, which mirrors the left half so the figure is exactly symmetrical, as logo.svg (white on a Nordic-blue disc) and logo-white.svg. It links home in the header, sits on the login page and is the favicon. The login page shows an angular "JARL" wordmark drawn as SVG paths over a rule with a "DNS" node, coloured from the theme. The header's "Jarl" uses a self-hosted Cinzel Bold subset (SIL OFL); jarld serves .woff2 as font/woff2. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
bf7f99874b
commit
a7d389be27
13 files changed
+336
-8
No files matched your search
@@ -0,0 +1,39 @@
|
||||
// The "JARL" wordmark for the login page: angular Norse-style letters
|
||||
// drawn as paths (no font needed), over a rule with DNS nodes. The letters
|
||||
// use the text color and the rule the accent color, so it follows the
|
||||
// theme.
|
||||
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" },
|
||||
];
|
||||
|
||||
export function wordmark() {
|
||||
const letterG = el("g", { fill: "currentColor", "fill-rule": "evenodd" },
|
||||
...letters.map((l) => el("path", { d: l.d, transform: `translate(${l.x} 0)` })));
|
||||
// The rule: tapered lines, two nodes and a "DNS" node in the middle.
|
||||
const rule = 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: "wordmark", viewBox: "-4 -4 288 162", role: "img", "aria-label": "Jarl" },
|
||||
el("title", null, "Jarl"), letterG, rule);
|
||||
}
|
||||
Reference in new issue
Block a user