branding: SimurgArray brand kit (mark, wordmark, lockups, icons, templates, guide)
Frontal dotted simurg on a bead grid: gold body and wings, three-dot crown, red / gold / green channel plumes with peacock eyes. Detailed (31x27), simple (11x10) and micro (7x7) drawings; dark, light, gold, black, white versions; outlined Noto Sans wordmark; favicon and app icons; README banner, social preview, avatar, featured-image template, report corner mark, CLI banner. Checks: WCAG contrast table, protan/deutan simulation, icon sizes, family sheet. Blog featured images regenerated with the new mark for consistency. Geometry shared in scripts/brand/simurg_mark.py.
This commit is contained in:
1 parent
ba38be122e
commit
558c198957
84 files changed
+823
-143
No files matched your search
@@ -0,0 +1,86 @@
|
||||
"""Geometry of the SimurgArray mark on its dot grid (no dependencies beyond the standard library).
|
||||
|
||||
A frontal simurg with raised wings (three feathers each), a three-dot crown and three tail plumes: red channel,
|
||||
gold, green channel, each ending in a peacock eye. Shapes are capsules, circles and an ellipse in grid units; a cell
|
||||
belongs to the first shape that contains its centre. ``SIMPLE`` and ``MICRO`` are hand-drawn small versions.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import math
|
||||
from typing import Any
|
||||
|
||||
|
||||
def _seg(px: float, py: float, a: tuple[float, float], b: tuple[float, float]) -> float:
|
||||
dx, dy = b[0] - a[0], b[1] - a[1]
|
||||
t = max(0.0, min(1.0, ((px - a[0]) * dx + (py - a[1]) * dy) / ((dx * dx + dy * dy) or 1.0)))
|
||||
return math.hypot(px - a[0] - t * dx, py - a[1] - t * dy)
|
||||
|
||||
|
||||
CX = 15.5
|
||||
_WING = [([(13.6, 9.6), (8, 5.2), (1.8, 1.4)], 1.25), ([(13.4, 11), (7.5, 8.4), (1.2, 6.6)], 1.25),
|
||||
([(13.4, 12.6), (8, 12), (2.6, 11.8)], 1.2)] # fmt: skip
|
||||
SHAPES: list[tuple[str, Any, str]] = []
|
||||
for pts, r in _WING:
|
||||
SHAPES.append(("cap", (pts, r), "gold"))
|
||||
SHAPES.append(("cap", ([(2 * CX - x, y) for x, y in pts], r), "gold"))
|
||||
SHAPES += [
|
||||
("circ", (CX, 4.4, 2.3), "gold"), ("cap", ([(CX, 6), (CX, 8)], 1.3), "gold"), # head, neck
|
||||
("circ", (CX, 1.2, 0.62), "gold"), ("circ", (13.6, 1.9, 0.62), "gold"), ("circ", (17.4, 1.9, 0.62), "gold"),
|
||||
("ell", (CX, 12.5, 2.9, 5.4), "gold"), # body
|
||||
("cap", ([(14.8, 17), (12.6, 20.5), (10.4, 23.2)], 0.7), "red"), ("circ", (10, 24.3, 1.6), "red"),
|
||||
("cap", ([(CX, 17.5), (CX, 23.2)], 0.7), "gold"), ("circ", (CX, 24.6, 1.6), "gold"),
|
||||
("cap", ([(16.2, 17), (18.4, 20.5), (20.6, 23.2)], 0.7), "green"), ("circ", (21, 24.3, 1.6), "green"),
|
||||
] # fmt: skip
|
||||
DETAILED_SIZE = (31, 27)
|
||||
SIMPLE = """
|
||||
X.........X
|
||||
XX.......XX
|
||||
.XX..X..XX.
|
||||
..XXXXXXX..
|
||||
XXXXXXXXXXX
|
||||
...XXXXX...
|
||||
....XXX....
|
||||
...R.X.G...
|
||||
..R..X..G..
|
||||
.RR.XXX.GG.
|
||||
"""
|
||||
MICRO = """
|
||||
X.....X
|
||||
XX.X.XX
|
||||
.XXXXX.
|
||||
..XXX..
|
||||
...X...
|
||||
.R.X.G.
|
||||
R..X..G
|
||||
"""
|
||||
Grid = dict[tuple[int, int], str]
|
||||
|
||||
|
||||
def _inside(x: float, y: float, kind: str, p: Any) -> bool:
|
||||
if kind == "circ":
|
||||
return math.hypot(x - p[0], y - p[1]) <= p[2]
|
||||
if kind == "cap":
|
||||
pts, r = p
|
||||
return min(_seg(x, y, pts[i], pts[i + 1]) for i in range(len(pts) - 1)) <= r
|
||||
cx, cy, rx, ry = p
|
||||
return ((x - cx) / rx) ** 2 + ((y - cy) / ry) ** 2 <= 1
|
||||
|
||||
|
||||
def detailed() -> tuple[Grid, int, int]:
|
||||
cols, rows = DETAILED_SIZE
|
||||
g: Grid = {}
|
||||
for r in range(rows):
|
||||
for c in range(cols):
|
||||
for kind, p, layer in SHAPES:
|
||||
if _inside(c + 0.5, r + 0.5, kind, p):
|
||||
g[(c, r)] = layer
|
||||
break
|
||||
return g, cols, rows
|
||||
|
||||
|
||||
def art(s: str) -> tuple[Grid, int, int]:
|
||||
lines = s.strip().splitlines()
|
||||
g = {(c, r): {"X": "gold", "R": "red", "G": "green"}[ch] for r, ln in enumerate(lines) for c, ch in enumerate(ln)
|
||||
if ch != "."} # fmt: skip
|
||||
return g, len(lines[0]), len(lines)
|
||||
Reference in new issue
Block a user