Skip to content

Commit 7ca0085

Browse files
lesnik512claude
andauthored
Org t-shirt apparel artwork (chest mark + back lockup) (#34)
* docs(planning): org t-shirt apparel design + plan Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(brand): apparel_back wordmark+URL lockup geometry Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(brand): apparel render target for the org t-shirt Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(brand): apparel print spec + architecture promotion Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(planning): match design snippet aria-label to shipped comma form Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent e3a2a36 commit 7ca0085

13 files changed

Lines changed: 583 additions & 0 deletions

File tree

architecture/brand-marks.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,15 @@ Repo READMEs embed these as a centered `<picture>` banner that replaces the
4545
leading `# <repo>` heading. The `<source>` elements reference the assets via
4646
absolute `raw.githubusercontent.com/modern-python/.github/main/brand/projects/<repo>/`
4747
URLs so no asset files are committed to the individual repos.
48+
49+
## Apparel (`brand/apparel/`)
50+
51+
Print-ready artwork for the black org t-shirt, generated by
52+
`brand/build/apparel.py::render_apparel` from the same primitives as the org
53+
marks, in the cream + gold-dark colorway (a 2-ink spot print). Two artworks:
54+
`chest-mark.svg` (the transparent chevron `geometry.mark`, left chest) and
55+
`back-lockup.svg` (`geometry.apparel_back` — the MODERN/PYTHON wordmark with
56+
`modern-python.org` outlined beneath it, viewBox `118 32 304 228`, back print).
57+
Each ships a 300 DPI PNG fallback (`chest-mark-1050.png` 3.5 in,
58+
`back-lockup-2400.png` 8 in). Regenerate via `uv run python -m brand.build.render`;
59+
placement and vendor notes live in `brand/apparel/README.md`.

brand/apparel/README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Apparel artwork
2+
3+
Print-ready artwork for the **black** modern-python org t-shirt, generated by
4+
`brand/build/apparel.py`. Regenerate with:
5+
6+
```bash
7+
uv run python -m brand.build.render
8+
```
9+
10+
## Colorway
11+
12+
Two-ink spot print, cream + gold-dark (the on-dark org treatment):
13+
14+
| Token | Hex | Role |
15+
|-------|-----|------|
16+
| Cream | `#f4f1e8` | MODERN, top crop, chevron snake |
17+
| Gold-dark | `#f0b528` | PYTHON, bottom crop, chevron, URL |
18+
19+
## Files
20+
21+
| File | Placement | Print size |
22+
|------|-----------|-----------|
23+
| `chest-mark.svg` / `chest-mark-1050.png` | Left chest, standard placement | ~3.5 in wide |
24+
| `back-lockup.svg` / `back-lockup-2400.png` | Back, centered, ~4-5 in below collar | ~8 in wide |
25+
26+
The transparent chevron mark is `geometry.mark`; the back lockup (wordmark +
27+
`modern-python.org`) is `geometry.apparel_back`. PNGs are 300 DPI fallbacks;
28+
prefer the SVGs (vector) for print. Send the vendor a black garment with a
29+
2-color print in the two hexes above.

brand/apparel/back-lockup-2400.png

34.1 KB
Loading

brand/apparel/back-lockup.svg

Lines changed: 1 addition & 0 deletions
Loading

brand/apparel/chest-mark-1050.png

5.53 KB
Loading

brand/apparel/chest-mark.svg

Lines changed: 1 addition & 0 deletions
Loading

brand/build/apparel.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from pathlib import Path
2+
3+
from brand.build import geometry as g
4+
from brand.build import tokens as t
5+
from brand.build.raster import export_png
6+
7+
ROOT = Path(__file__).resolve().parents[2]
8+
APPAREL = ROOT / "brand" / "apparel"
9+
10+
11+
def _write(path: Path, content: str) -> None:
12+
path.parent.mkdir(parents=True, exist_ok=True)
13+
path.write_text(content + "\n", encoding="utf-8")
14+
15+
16+
def render_apparel() -> None:
17+
"""Print-ready artwork for the black org t-shirt: a transparent left-chest
18+
chevron mark and a back wordmark+URL lockup, both cream + gold-dark. SVG is
19+
the master; PNGs are 300 DPI print fallbacks (chest 3.5 in, back 8 in)."""
20+
APPAREL.mkdir(parents=True, exist_ok=True)
21+
ink = dict(struct=t.CREAM, gold=t.GOLD_DARK)
22+
_write(APPAREL / "chest-mark.svg", g.mark(**ink))
23+
export_png(APPAREL / "chest-mark.svg", APPAREL / "chest-mark-1050.png", width=1050)
24+
_write(APPAREL / "back-lockup.svg", g.apparel_back(**ink))
25+
export_png(APPAREL / "back-lockup.svg", APPAREL / "back-lockup-2400.png", width=2400)

brand/build/geometry.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,28 @@ def mark(*, struct: str, gold: str) -> str:
8383
return _SVG_OPEN.format(w=100, h=100) + _icon_mark(struct, gold) + "</svg>"
8484

8585

86+
def apparel_back(*, struct: str, gold: str) -> str:
87+
"""Back-of-shirt lockup: the MODERN/PYTHON wordmark with the full domain
88+
outlined beneath it, transparent, for the cream+gold-dark colorway. Extends
89+
the `wordmark` viewBox downward to seat the URL centered on the same axis."""
90+
url, _ = outline_text(
91+
"modern-python.org",
92+
18,
93+
x=270,
94+
baseline_y=240,
95+
anchor="middle",
96+
color=gold,
97+
letter_spacing=3,
98+
)
99+
return (
100+
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="118 32 304 228" '
101+
'role="img" aria-label="Modern Python, modern-python.org">'
102+
+ lockup_body(struct=struct, gold=gold)
103+
+ url
104+
+ "</svg>"
105+
)
106+
107+
86108
def social_card(*, bg: str, struct: str, gold: str, url_color: str) -> str:
87109
body = lockup_body(struct=struct, gold=gold)
88110
url, _ = outline_text(

brand/build/render.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from brand.build import geometry as g
44
from brand.build import tokens as t
5+
from brand.build.apparel import render_apparel
56
from brand.build.projects import render_projects
67
from brand.build.raster import export_png
78

@@ -93,6 +94,9 @@ def render() -> None:
9394
# Per-project marks (brand/projects/<repo>/).
9495
render_projects()
9596

97+
# Apparel artwork (brand/apparel/).
98+
render_apparel()
99+
96100

97101
def main() -> None:
98102
render()

0 commit comments

Comments
 (0)