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
@@ -1,5 +1,6 @@
|
||||
// Jarl web UI: router, layout and login.
|
||||
import { h, mount, toast, errorBox, plural } from "./ui.js";
|
||||
import { wordmark } from "./brand.js";
|
||||
import { api, get, state, loadDraft, onChange, setUnauthorizedHandler, setImmediate } from "./api.js";
|
||||
import * as dashboard from "./pages/dashboard.js";
|
||||
import * as zones from "./pages/zones.js";
|
||||
@@ -74,7 +75,8 @@ function renderLogin(message) {
|
||||
}
|
||||
} }, user, pass, h("button", { class: "primary", type: "submit" }, "Log in"), err);
|
||||
mount(app, h("div", { class: "login panel" },
|
||||
h("h1", null, "Jarl"),
|
||||
h("img", { class: "login-logo", src: "/assets/logo.svg", alt: "", width: 104, height: 104 }),
|
||||
h("h1", null, wordmark()),
|
||||
h("div", { class: "tag" }, "Rule your DNS holds"),
|
||||
message ? h("div", { class: "msg warn" }, message) : null,
|
||||
form));
|
||||
@@ -88,7 +90,10 @@ function layout() {
|
||||
const q = h("input", { type: "search", placeholder: "Search names, data…", "aria-label": "Search" });
|
||||
const me = state.me;
|
||||
const header = h("header", { class: "top" },
|
||||
h("a", { class: "brand", href: "#/" }, "Jarl", h("span", null, me.version)),
|
||||
h("a", { class: "brand", href: "#/", title: "Dashboard" },
|
||||
h("img", { src: "/assets/logo.svg", alt: "", width: 30, height: 30 }),
|
||||
h("span", { class: "brand-name" }, "Jarl"),
|
||||
h("span", { class: "brand-version" }, me.version)),
|
||||
navEl,
|
||||
h("div", { class: "spacer" }),
|
||||
h("form", { class: "search", onsubmit: (e) => { e.preventDefault(); if (q.value.trim()) location.hash = "#/search?q=" + encodeURIComponent(q.value.trim()); } }, q),
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
Copyright 2020 The Cinzel Project Authors (https://github.com/NDISCOVER/Cinzel)
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
Binary file not shown.
@@ -0,0 +1,30 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="20 -1 88 130" role="img" aria-labelledby="t">
|
||||
<title id="t">Jarl</title>
|
||||
<!-- Jarl: a Viking ruler in a spear-pointed crown, drawn like a woodcut.
|
||||
The crown holds a DNS tree: the root node with its branches below.
|
||||
Generated by scripts/logo.py, which mirrors the left half, so it is
|
||||
exactly symmetrical; the beard's strands are cut out with a mask. -->
|
||||
<path fill="none" stroke="#fff" stroke-width="3.6" stroke-linejoin="miter" stroke-miterlimit="8" d="M36 44 L35 28 L32 18 L41 25 L50 30 L55 21 L64 9 L73 21 L78 30 L87 25 L96 18 L93 28 L92 44 Z"/>
|
||||
<path fill="#fff" d="M37 37 H91 V40.5 H37 Z"/>
|
||||
<path fill="#fff" d="M32 18 L27.5 9 L37 13.5 Z M96 18 L100.5 9 L91 13.5 Z M64 9 L61 3.5 L64 0.5 L67 3.5 Z"/>
|
||||
<g fill="none" stroke="#fff" stroke-width="2.3"><circle cx="64" cy="19" r="3"/><path d="M64 22 V28.5 M55.3 31.5 H72.7"/><circle cx="52.2" cy="31.5" r="3"/><circle cx="75.8" cy="31.5" r="3"/></g>
|
||||
<circle cx="64" cy="31.5" r="3.2" fill="#fff"/>
|
||||
<defs><mask id="jarl-cut-white" maskUnits="userSpaceOnUse" x="0" y="0" width="128" height="128"><rect width="128" height="128" fill="#fff"/><g fill="none" stroke="#000" stroke-linecap="round"><path stroke-width="2.0" d="M40 80 C42.5 86 37 91 39.5 99 C40.5 102 39 104 40 106"/><path stroke-width="2.0" d="M 88 80 C 85.5 86 91 91 88.5 99 C 87.5 102 89 104 88 106"/><path stroke-width="1.7" d="M44.5 86 C47 92 42 97 44.5 106"/><path stroke-width="1.7" d="M 83.5 86 C 81 92 86 97 83.5 106"/><path stroke-width="1.5" d="M48.5 85.5 C50.5 90 47 94 48.5 99"/><path stroke-width="1.5" d="M 79.5 85.5 C 77.5 90 81 94 79.5 99"/><path stroke-width="2.0" d="M50.5 92 C53 99 48.5 104 51 113"/><path stroke-width="2.0" d="M 77.5 92 C 75 99 79.5 104 77 113"/><path stroke-width="1.7" d="M54.5 86.5 C57 94 52.5 101 55 109"/><path stroke-width="1.7" d="M 73.5 86.5 C 71 94 75.5 101 73 109"/><path stroke-width="1.8" d="M58 95 C59.5 101 56.5 106 58.5 116"/><path stroke-width="1.8" d="M 70 95 C 68.5 101 71.5 106 69.5 116"/><path stroke-width="1.5" d="M60.8 85.5 C62.3 92 59.8 98 61.2 105"/><path stroke-width="1.5" d="M 67.2 85.5 C 65.7 92 68.2 98 66.8 105"/><path stroke-width="1.4" d="M46 101.5 C47 104 45.5 106.5 46.5 109.5"/><path stroke-width="1.4" d="M 82 101.5 C 81 104 82.5 106.5 81.5 109.5"/><path stroke-width="1.4" d="M62.2 109 C62.7 113 61.7 116 62.4 119.5"/><path stroke-width="1.4" d="M 65.8 109 C 65.3 113 66.3 116 65.6 119.5"/><path stroke-width="1.3" d="M56.5 77.6 Q49.5 79.2 43 85.5"/><path stroke-width="1.3" d="M 71.5 77.6 Q 78.5 79.2 85 85.5"/><path stroke-width="2.4" d="M58.6 81.6 Q49.5 83.8 41.5 95"/><path stroke-width="2.4" d="M 69.4 81.6 Q 78.5 83.8 86.5 95"/><path stroke-width="1.8" d="M60.4 82.2 H67.6"/></g></mask></defs>
|
||||
<g fill="#fff" fill-rule="evenodd" mask="url(#jarl-cut-white)">
|
||||
<path d="M40 46 H88 L86.5 50 L71.5 55.5 L66.5 62.5 L61.5 62.5 L56.5 55.5 L41.5 50 Z"/>
|
||||
<path d="M61.5 63 H66.5 L69 72.5 L64 75.5 L59 72.5 Z"/>
|
||||
<path d="M38 69 L45 73.5 L63 79.5 H65 L83 73.5 L90 69 Q95 84 92 96 L88 104 L86 101 L83 110 L80 106 L76 116 L73 111 L69 121 L66 116 L64 127 L62 116 L59 121 L55 111 L52 116 L48 106 L45 110 L42 101 L40 104 L36 96 Q33 84 38 69 Z"/>
|
||||
<path d="M33 46 L37 46 Q35 64 30 78 Q26 88 24 100 Q22 84 26 72 Q31 60 33 46 Z"/>
|
||||
<path d="M 95 46 L 91 46 Q 93 64 98 78 Q 102 88 104 100 Q 106 84 102 72 Q 97 60 95 46 Z"/>
|
||||
<path d="M38 47 L42 47 Q41 66 37 82 Q34 92 33 104 Q31 88 34 76 Q37 62 38 47 Z"/>
|
||||
<path d="M 90 47 L 86 47 Q 87 66 91 82 Q 94 92 95 104 Q 97 88 94 76 Q 91 62 90 47 Z"/>
|
||||
<path d="M41 51 L44.5 55 L44 63 L41.5 59 Z"/>
|
||||
<path d="M 87 51 L 83.5 55 L 84 63 L 86.5 59 Z"/>
|
||||
<path d="M47 58 Q52.5 55 58 59.5 Q52.5 63 47 58 Z M51.4 59 L53 57.4 L54.6 59 L53 60.6 Z"/>
|
||||
<path d="M 81 58 Q 75.5 55 70 59.5 Q 75.5 63 81 58 Z M 76.6 59 L 75 57.4 L 73.4 59 L 75 60.6 Z"/>
|
||||
<path d="M45 61.5 L54.5 65 L57.5 72.5 L50 73 L45.5 67.5 Z"/>
|
||||
<path d="M 83 61.5 L 73.5 65 L 70.5 72.5 L 78 73 L 82.5 67.5 Z"/>
|
||||
<path d="M63 76 L57 75 L48 78 Q42 82 38 92 Q45 85 50 83 L57 80.5 L63 80 Z"/>
|
||||
<path d="M 65 76 L 71 75 L 80 78 Q 86 82 90 92 Q 83 85 78 83 L 71 80.5 L 65 80 Z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.1 KiB |
@@ -0,0 +1,33 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" role="img" aria-labelledby="t">
|
||||
<title id="t">Jarl</title>
|
||||
<!-- Jarl: a Viking ruler in a spear-pointed crown, drawn like a woodcut.
|
||||
The crown holds a DNS tree: the root node with its branches below.
|
||||
Generated by scripts/logo.py, which mirrors the left half, so it is
|
||||
exactly symmetrical; the beard's strands are cut out with a mask. -->
|
||||
<circle cx="64" cy="64" r="64" fill="#2f5fb3"/>
|
||||
<g transform="translate(64 66) scale(0.8) translate(-64 -64)">
|
||||
<path fill="none" stroke="#fff" stroke-width="3.6" stroke-linejoin="miter" stroke-miterlimit="8" d="M36 44 L35 28 L32 18 L41 25 L50 30 L55 21 L64 9 L73 21 L78 30 L87 25 L96 18 L93 28 L92 44 Z"/>
|
||||
<path fill="#fff" d="M37 37 H91 V40.5 H37 Z"/>
|
||||
<path fill="#fff" d="M32 18 L27.5 9 L37 13.5 Z M96 18 L100.5 9 L91 13.5 Z M64 9 L61 3.5 L64 0.5 L67 3.5 Z"/>
|
||||
<g fill="none" stroke="#fff" stroke-width="2.3"><circle cx="64" cy="19" r="3"/><path d="M64 22 V28.5 M55.3 31.5 H72.7"/><circle cx="52.2" cy="31.5" r="3"/><circle cx="75.8" cy="31.5" r="3"/></g>
|
||||
<circle cx="64" cy="31.5" r="3.2" fill="#fff"/>
|
||||
<defs><mask id="jarl-cut" maskUnits="userSpaceOnUse" x="0" y="0" width="128" height="128"><rect width="128" height="128" fill="#fff"/><g fill="none" stroke="#000" stroke-linecap="round"><path stroke-width="2.0" d="M40 80 C42.5 86 37 91 39.5 99 C40.5 102 39 104 40 106"/><path stroke-width="2.0" d="M 88 80 C 85.5 86 91 91 88.5 99 C 87.5 102 89 104 88 106"/><path stroke-width="1.7" d="M44.5 86 C47 92 42 97 44.5 106"/><path stroke-width="1.7" d="M 83.5 86 C 81 92 86 97 83.5 106"/><path stroke-width="1.5" d="M48.5 85.5 C50.5 90 47 94 48.5 99"/><path stroke-width="1.5" d="M 79.5 85.5 C 77.5 90 81 94 79.5 99"/><path stroke-width="2.0" d="M50.5 92 C53 99 48.5 104 51 113"/><path stroke-width="2.0" d="M 77.5 92 C 75 99 79.5 104 77 113"/><path stroke-width="1.7" d="M54.5 86.5 C57 94 52.5 101 55 109"/><path stroke-width="1.7" d="M 73.5 86.5 C 71 94 75.5 101 73 109"/><path stroke-width="1.8" d="M58 95 C59.5 101 56.5 106 58.5 116"/><path stroke-width="1.8" d="M 70 95 C 68.5 101 71.5 106 69.5 116"/><path stroke-width="1.5" d="M60.8 85.5 C62.3 92 59.8 98 61.2 105"/><path stroke-width="1.5" d="M 67.2 85.5 C 65.7 92 68.2 98 66.8 105"/><path stroke-width="1.4" d="M46 101.5 C47 104 45.5 106.5 46.5 109.5"/><path stroke-width="1.4" d="M 82 101.5 C 81 104 82.5 106.5 81.5 109.5"/><path stroke-width="1.4" d="M62.2 109 C62.7 113 61.7 116 62.4 119.5"/><path stroke-width="1.4" d="M 65.8 109 C 65.3 113 66.3 116 65.6 119.5"/><path stroke-width="1.3" d="M56.5 77.6 Q49.5 79.2 43 85.5"/><path stroke-width="1.3" d="M 71.5 77.6 Q 78.5 79.2 85 85.5"/><path stroke-width="2.4" d="M58.6 81.6 Q49.5 83.8 41.5 95"/><path stroke-width="2.4" d="M 69.4 81.6 Q 78.5 83.8 86.5 95"/><path stroke-width="1.8" d="M60.4 82.2 H67.6"/></g></mask></defs>
|
||||
<g fill="#fff" fill-rule="evenodd" mask="url(#jarl-cut)">
|
||||
<path d="M40 46 H88 L86.5 50 L71.5 55.5 L66.5 62.5 L61.5 62.5 L56.5 55.5 L41.5 50 Z"/>
|
||||
<path d="M61.5 63 H66.5 L69 72.5 L64 75.5 L59 72.5 Z"/>
|
||||
<path d="M38 69 L45 73.5 L63 79.5 H65 L83 73.5 L90 69 Q95 84 92 96 L88 104 L86 101 L83 110 L80 106 L76 116 L73 111 L69 121 L66 116 L64 127 L62 116 L59 121 L55 111 L52 116 L48 106 L45 110 L42 101 L40 104 L36 96 Q33 84 38 69 Z"/>
|
||||
<path d="M33 46 L37 46 Q35 64 30 78 Q26 88 24 100 Q22 84 26 72 Q31 60 33 46 Z"/>
|
||||
<path d="M 95 46 L 91 46 Q 93 64 98 78 Q 102 88 104 100 Q 106 84 102 72 Q 97 60 95 46 Z"/>
|
||||
<path d="M38 47 L42 47 Q41 66 37 82 Q34 92 33 104 Q31 88 34 76 Q37 62 38 47 Z"/>
|
||||
<path d="M 90 47 L 86 47 Q 87 66 91 82 Q 94 92 95 104 Q 97 88 94 76 Q 91 62 90 47 Z"/>
|
||||
<path d="M41 51 L44.5 55 L44 63 L41.5 59 Z"/>
|
||||
<path d="M 87 51 L 83.5 55 L 84 63 L 86.5 59 Z"/>
|
||||
<path d="M47 58 Q52.5 55 58 59.5 Q52.5 63 47 58 Z M51.4 59 L53 57.4 L54.6 59 L53 60.6 Z"/>
|
||||
<path d="M 81 58 Q 75.5 55 70 59.5 Q 75.5 63 81 58 Z M 76.6 59 L 75 57.4 L 73.4 59 L 75 60.6 Z"/>
|
||||
<path d="M45 61.5 L54.5 65 L57.5 72.5 L50 73 L45.5 67.5 Z"/>
|
||||
<path d="M 83 61.5 L 73.5 65 L 70.5 72.5 L 78 73 L 82.5 67.5 Z"/>
|
||||
<path d="M63 76 L57 75 L48 78 Q42 82 38 92 Q45 85 50 83 L57 80.5 L63 80 Z"/>
|
||||
<path d="M 65 76 L 71 75 L 80 78 Q 86 82 90 92 Q 83 85 78 83 L 71 80.5 L 65 80 Z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.2 KiB |
@@ -87,9 +87,23 @@ header.top {
|
||||
background: var(--panel); border-bottom: 1px solid var(--border);
|
||||
padding: 8px 16px; position: sticky; top: 0; z-index: 10;
|
||||
}
|
||||
header.top .brand { font-weight: 700; font-size: 17px; letter-spacing: 0.5px; color: var(--text); }
|
||||
header.top .brand span { color: var(--muted); font-weight: 400; font-size: 12px; margin-left: 6px; }
|
||||
header.top .brand:hover { text-decoration: none; color: var(--accent); }
|
||||
/* The brand face: Cinzel Bold (SIL OFL, assets/fonts/Cinzel-OFL.txt),
|
||||
subset to Latin and served by jarld itself. */
|
||||
@font-face {
|
||||
font-family: "Jarl Cinzel";
|
||||
src: url("fonts/cinzel-bold.woff2") format("woff2");
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
.brand-name { font-family: "Jarl Cinzel", "Cinzel", "Trajan Pro", Georgia, serif; font-weight: 700; letter-spacing: 1.5px; }
|
||||
header.top .brand { display: inline-flex; align-items: center; gap: 8px; color: var(--text); text-decoration: none; }
|
||||
header.top .brand img { display: block; transition: transform 0.15s; }
|
||||
header.top .brand .brand-name { font-size: 20px; line-height: 1; padding-top: 2px; }
|
||||
header.top .brand .brand-version { color: var(--muted); font-size: 12px; align-self: flex-end; padding-bottom: 2px; }
|
||||
header.top .brand:hover { text-decoration: none; }
|
||||
header.top .brand:hover .brand-name { color: var(--accent); }
|
||||
header.top .brand:hover img { transform: scale(1.06); }
|
||||
nav.main { display: flex; gap: 2px; flex-wrap: wrap; }
|
||||
nav.main a { padding: 6px 10px; border-radius: var(--radius); color: var(--text); }
|
||||
nav.main a:hover { background: var(--info-soft); text-decoration: none; }
|
||||
@@ -215,7 +229,12 @@ button:disabled { opacity: 0.5; cursor: not-allowed; }
|
||||
|
||||
/* Login */
|
||||
.login { max-width: 360px; margin: 10vh auto; }
|
||||
.login h1 { font-size: 26px; text-align: center; margin-bottom: 4px; }
|
||||
.login-logo { display: block; margin: 8px auto 10px; }
|
||||
.login h1 { text-align: center; margin: 0 0 8px; }
|
||||
.wordmark { display: block; width: 220px; height: auto; margin: 0 auto; color: var(--text); }
|
||||
.wordmark-rule .fill { fill: var(--accent); }
|
||||
.wordmark-rule .line { fill: none; stroke: var(--accent); stroke-width: 2.6; }
|
||||
.wordmark-rule .dns { fill: var(--accent); font: 700 12.5px system-ui, sans-serif; letter-spacing: 0.5px; }
|
||||
.login .tag { text-align: center; color: var(--muted); margin-bottom: 18px; }
|
||||
.login form { display: flex; flex-direction: column; gap: 10px; }
|
||||
.login input { width: 100%; padding: 8px 10px; }
|
||||
@@ -362,3 +381,7 @@ button.chip:hover { background: var(--accent-soft); border-color: var(--accent);
|
||||
.name-preview .msg, .will-add .msg { margin: 4px 0 0; padding: 3px 8px; }
|
||||
.will-add { margin-top: 8px; font-size: 13px; }
|
||||
.will-add code { font-family: var(--mono); background: var(--code-bg); padding: 1px 6px; border-radius: 4px; word-break: break-all; }
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
header.top .brand img { transition: none; }
|
||||
header.top .brand:hover img { transform: none; }
|
||||
}
|
||||
Reference in new issue
Block a user