krz/krz.sh

clone: git clone https://gitbay.org/krz/krz.sh.git

4dc703b26d085ffa13eec37da79076f895e55692

verified · cmc

author: Christian Cleberg <hello@cleberg.net> · 2026-08-12T05:29:10Z

add logo sources under assets/

og.png and apple-touch-icon.png were built from svgs that only existed
outside the repo, so the social card's baked-in text was not editable.
build.sh regenerates both from source and reproduces the committed
files byte for byte. mark.py renders the standalone mark to png.

zola only publishes static/ and content/, so none of this reaches the
deployed site.
 README.nfo       |  1 +
 assets/build.sh  | 20 ++++++++++++++++++
 assets/mark.py   | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 assets/og.svg    | 21 +++++++++++++++++++
 assets/touch.svg | 12 +++++++++++
 5 files changed, 116 insertions(+)

diff --git a/README.nfo b/README.nfo
index f8e7e38..859d450 100644
--- a/README.nfo
+++ b/README.nfo
@@ -21,6 +21,7 @@ STRUCTURE
   templates/       tera templates
   sass/main.scss   styles, compiled to main.css
   static/          assets, favicon.svg, CNAME
+  assets/          logo sources; build.sh regenerates the icons
 
 DEPLOY
   pushing to main builds and publishes to github pages via
diff --git a/assets/build.sh b/assets/build.sh
new file mode 100755
index 0000000..78dfe6b
--- /dev/null
+++ b/assets/build.sh
@@ -0,0 +1,20 @@
+#!/usr/bin/env bash
+# Regenerate the raster icons in static/ from the sources here.
+# macOS only: qlmanage rasterizes the svg, sips crops it.
+set -euo pipefail
+cd "$(dirname "$0")"
+
+out=../static
+tmp=$(mktemp -d)
+trap 'rm -rf "$tmp"' EXIT
+
+# qlmanage always renders square, so og.svg is authored 1200x1200 with the
+# 630-tall band centred, then cropped back to size afterwards.
+qlmanage -t -s 1200 -o "$tmp" og.svg >/dev/null
+sips -c 630 1200 "$tmp/og.svg.png" >/dev/null
+cp "$tmp/og.svg.png" "$out/og.png"
+
+qlmanage -t -s 180 -o "$tmp" touch.svg >/dev/null
+cp "$tmp/touch.svg.png" "$out/apple-touch-icon.png"
+
+echo "wrote $out/og.png and $out/apple-touch-icon.png"
diff --git a/assets/mark.py b/assets/mark.py
new file mode 100644
index 0000000..7b177b3
--- /dev/null
+++ b/assets/mark.py
@@ -0,0 +1,62 @@
+#!/usr/bin/env python3
+"""Render the krz frame mark to RGBA PNG at exact integer pixel boundaries."""
+import struct, zlib, sys
+
+GRID = 32
+# (x, y, w, h) in grid units
+FRAME = [(4, 4, 24, 4), (4, 24, 24, 4), (4, 8, 4, 16), (24, 8, 4, 16)]
+BLOCK = (12, 12, 8, 8)
+
+INKS = {
+    "dark":  ("#17171a", "#2f6bd6"),   # for light backgrounds
+    "light": ("#f1f1ef", "#6f9dff"),   # for dark backgrounds
+}
+
+
+def rgba(hexstr):
+    h = hexstr.lstrip("#")
+    return (int(h[0:2], 16), int(h[2:4], 16), int(h[4:6], 16), 255)
+
+
+def chunk(tag, data):
+    return (struct.pack(">I", len(data)) + tag + data
+            + struct.pack(">I", zlib.crc32(tag + data) & 0xFFFFFFFF))
+
+
+def render(size, fg_hex, ac_hex, path):
+    if size % GRID:
+        sys.exit(f"size {size} must be a multiple of {GRID}")
+    s = size // GRID
+    fg, ac = rgba(fg_hex), rgba(ac_hex)
+    # transparent canvas
+    px = bytearray(size * size * 4)
+
+    def fill(rect, color):
+        x, y, w, h = (v * s for v in rect)
+        row = bytes(color) * w
+        for yy in range(y, y + h):
+            off = (yy * size + x) * 4
+            px[off:off + w * 4] = row
+
+    for r in FRAME:
+        fill(r, fg)
+    fill(BLOCK, ac)
+
+    # filter byte 0 per scanline
+    raw = b"".join(b"\x00" + bytes(px[r * size * 4:(r + 1) * size * 4])
+                   for r in range(size))
+    png = (b"\x89PNG\r\n\x1a\n"
+           + chunk(b"IHDR", struct.pack(">IIBBBBB", size, size, 8, 6, 0, 0, 0))
+           + chunk(b"IDAT", zlib.compress(raw, 9))
+           + chunk(b"IEND", b""))
+    with open(path, "wb") as f:
+        f.write(png)
+    return len(png)
+
+
+if __name__ == "__main__":
+    for name, (fg, ac) in INKS.items():
+        for size in (1024, 512):
+            p = f"krz-mark-{size}-{name}.png"
+            n = render(size, fg, ac, p)
+            print(f"{p:28} {size}x{size}  {n:,}b")
diff --git a/assets/og.svg b/assets/og.svg
new file mode 100644
index 0000000..0afaf56
--- /dev/null
+++ b/assets/og.svg
@@ -0,0 +1,21 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="1200" viewBox="0 0 1200 1200">
+  <rect width="1200" height="1200" fill="#fbfbf9"/>
+  <!-- content band: 1200x630, centered vertically for a post-render crop -->
+  <g transform="translate(0,285)">
+    <rect x="48" y="48" width="1104" height="534" fill="none" stroke="#d9d8d2" stroke-width="2"/>
+
+    <!-- mark, 120x120 at (112,225) -->
+    <g transform="translate(112,225) scale(3.75)">
+      <g fill="#17171a">
+        <rect x="4" y="4" width="24" height="4"/>
+        <rect x="4" y="24" width="24" height="4"/>
+        <rect x="4" y="8" width="4" height="16"/>
+        <rect x="24" y="8" width="4" height="16"/>
+      </g>
+      <rect x="12" y="12" width="8" height="8" fill="#2f6bd6"/>
+    </g>
+
+    <text x="272" y="314" font-family="SF Mono, Menlo, monospace" font-size="84" font-weight="700" fill="#17171a" letter-spacing="-2">krz.sh</text>
+    <text x="112" y="403" font-family="SF Mono, Menlo, monospace" font-size="24" fill="#5c5c5f">Small, durable software focused on utility, privacy, and control.</text>
+  </g>
+</svg>
diff --git a/assets/touch.svg b/assets/touch.svg
new file mode 100644
index 0000000..fe33db3
--- /dev/null
+++ b/assets/touch.svg
@@ -0,0 +1,12 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="180" height="180" viewBox="0 0 32 32">
+  <rect width="32" height="32" fill="#fbfbf9"/>
+  <g transform="translate(3.2,3.2) scale(0.8)">
+    <g fill="#17171a">
+      <rect x="4" y="4" width="24" height="4"/>
+      <rect x="4" y="24" width="24" height="4"/>
+      <rect x="4" y="8" width="4" height="16"/>
+      <rect x="24" y="8" width="4" height="16"/>
+    </g>
+    <rect x="12" y="12" width="8" height="8" fill="#2f6bd6"/>
+  </g>
+</svg>