Skip to content

Commit 208eefe

Browse files
lesnik512claude
andcommitted
fix(brand): correct Boosty cover to 8:1 header (1920x240)
Boosty's profile header slot is 1920x240 (8:1), per Boosty creator guides; the initial 4:1/1920x480 would have been cropped. The 240px strip is too short to stack, so the lockup and tagline now sit side by side, centered as a pair using the measured tagline width. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 14d0ca2 commit 208eefe

9 files changed

Lines changed: 114 additions & 85 deletions

File tree

architecture/brand-marks.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@ The org's logo assets, generated by `brand/build/` (no frontmatter; living prose
66
Favicon, avatar, social cards — the interlocked-snakes pinwheel with a chevron.
77
Used everywhere small (favicons, avatars). See `site-branding.md` for site wiring.
88

9-
`boosty-cover.svg|png` is a 1920×480 (4:1) green-colorway profile-header banner
10-
for the org's Boosty page (`boosty.to/lesnik512`): the centered MODERN/PYTHON
11-
`geometry.lockup_body` over the outlined tagline `Open-source Python for
12-
production`, on the green surface. Generated by `geometry.boosty_cover`; the
13-
lower-left is kept clear for Boosty's avatar/name overlay. Not served by the
14-
docs site (excluded from `just sync-assets`); re-export at other sizes by
9+
`boosty-cover.svg|png` is a 1920×240 (8:1, Boosty's header slot) green-colorway
10+
profile-header banner for the org's Boosty page (`boosty.to/lesnik512`): the
11+
MODERN/PYTHON `geometry.lockup_body` and the outlined tagline `Open-source Python
12+
for production` set side by side (the 240 px strip is too short to stack),
13+
centered as a pair on the green surface. Generated by `geometry.boosty_cover`;
14+
the centered row stays clear of Boosty's lower-left avatar overlay. Not served by
15+
the docs site (excluded from `just sync-assets`); re-export at other sizes by
1516
changing only the `export_png` dimensions in `render.py`.
1617

1718
## Per-project marks (`brand/projects/<repo>/`)

brand/build/geometry.py

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -139,25 +139,41 @@ def social_square(*, bg: str, struct: str, gold: str) -> str:
139139

140140

141141
def boosty_cover(*, bg: str, struct: str, gold: str) -> str:
142-
"""Wide Boosty profile-header banner: the MODERN/PYTHON lockup centered over
143-
an outlined tagline, on a full-bleed background. 4:1 (1920x480); the
144-
lower-left is left clear for Boosty's avatar/name overlay."""
142+
"""Boosty profile-header banner — 8:1 (1920x240), Boosty's documented header
143+
size. The strip is too shallow to stack, so the MODERN/PYTHON lockup and the
144+
outlined tagline sit side by side, centered as a pair on a full-bleed
145+
background. The tagline width is measured to center the whole row."""
146+
w, h = 1920, 240
147+
s = 0.9 # lockup scale; its visual box is x[134,406] (width 272), y-center 125
148+
lock_w = 272 * s
149+
tagline_text = "Open-source Python for production"
150+
tag_size = 40
151+
gap = 60 # px between lockup and tagline
152+
_, tag_w = outline_text(
153+
tagline_text,
154+
tag_size,
155+
x=0,
156+
baseline_y=0,
157+
anchor="start",
158+
color=gold,
159+
letter_spacing=4,
160+
)
161+
x0 = (w - (lock_w + gap + tag_w)) / 2 # left edge of the centered row
162+
tx = round(x0 - 134 * s, 1) # seat the lockup's visual-left at x0
163+
ty = round(h / 2 - 125 * s, 1) # center the lockup vertically
145164
body = lockup_body(struct=struct, gold=gold)
146-
s = 1.4
147-
tx = round(1920 / 2 - 270 * s, 1) # box-center horizontally (lockup box 540 wide)
148-
ty = round(200 - 125 * s, 1) # lockup center ~y200, leaving room for the tagline
149165
tagline, _ = outline_text(
150-
"Open-source Python for production",
151-
30,
152-
x=960,
153-
baseline_y=400,
154-
anchor="middle",
166+
tagline_text,
167+
tag_size,
168+
x=round(x0 + lock_w + gap, 1),
169+
baseline_y=round(h / 2 + tag_size * 0.32, 1), # optical vertical center
170+
anchor="start",
155171
color=gold,
156172
letter_spacing=4,
157173
)
158174
return (
159-
_SVG_OPEN.format(w=1920, h=480)
160-
+ f'<rect width="1920" height="480" fill="{bg}"/>'
175+
_SVG_OPEN.format(w=w, h=h)
176+
+ f'<rect width="{w}" height="{h}" fill="{bg}"/>'
161177
+ f'<g transform="translate({tx},{ty}) scale({s})">{body}</g>'
162178
+ tagline
163179
+ "</svg>"

brand/build/render.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ def render() -> None:
7878
g.boosty_cover(bg=t.GREEN_SURFACE, struct=t.CREAM, gold=t.GOLD_DARK),
7979
)
8080
export_png(
81-
ORG / "boosty-cover.svg", ORG / "boosty-cover.png", width=1920, height=480
81+
ORG / "boosty-cover.svg", ORG / "boosty-cover.png", width=1920, height=240
8282
)
8383

8484
# Square (Telegram / square social) — cream + green.

brand/org/boosty-cover.png

-1.16 KB
Loading

brand/org/boosty-cover.svg

Lines changed: 1 addition & 1 deletion
Loading
Lines changed: 59 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
summary: Add a Boosty profile cover to the brand generator — a wide 1920x480 green-colorway banner (MODERN/PYTHON lockup + "Open-source Python for production" tagline) as SVG + PNG in brand/org/.
2+
summary: Add a Boosty profile cover to the brand generator — an 8:1 1920x240 green-colorway header banner (MODERN/PYTHON lockup + "Open-source Python for production" tagline, side by side) as SVG + PNG in brand/org/.
33
---
44

55
# Design: modern-python Boosty profile cover
@@ -8,14 +8,15 @@ summary: Add a Boosty profile cover to the brand generator — a wide 1920x480 g
88

99
Add a new **Boosty cover** output to the brand kit (`brand/build/`) that renders
1010
a wide profile-header banner for the org's Boosty page (`boosty.to/lesnik512`).
11-
It is the green colorway (green surface `#2f5e4a` with cream + gold-dark ink) —
12-
the same treatment as `social-card-green` and the org avatar — so the banner
13-
sits as one green field beside the (green) Boosty avatar. The composition is the
14-
existing MODERN/PYTHON `lockup_body` centered above the outlined tagline
15-
`Open-source Python for production`. Everything is drawn from existing
16-
`geometry.py` primitives; the only new geometry is the wide-banner composition.
17-
Outputs land in `brand/org/` as vector SVG plus a 1920×480 PNG, regenerable via
18-
`uv run python -m brand.build.render`.
11+
It is **8:1 at 1920×240** — Boosty's documented profile-header size. It uses the
12+
green colorway (green surface `#2f5e4a` with cream + gold-dark ink) — the same
13+
treatment as `social-card-green` and the org avatar — so the banner sits as one
14+
green field beside the (green) Boosty avatar. The short strip is too shallow to
15+
stack, so the existing MODERN/PYTHON `lockup_body` and the outlined tagline
16+
`Open-source Python for production` sit **side by side**, centered as a pair.
17+
Everything is drawn from existing `geometry.py` primitives; the only new geometry
18+
is the horizontal-banner composition. Outputs land in `brand/org/` as vector SVG
19+
plus a 1920×240 PNG, regenerable via `uv run python -m brand.build.render`.
1920

2021
## Motivation
2122

@@ -42,71 +43,80 @@ interactively against a rendered draft.
4243
### 1. Cover geometry — `brand/build/geometry.py`
4344

4445
Add `boosty_cover(*, bg, struct, gold)`: a complete `<svg>` (viewBox
45-
`0 0 1920 480`) with a full-bleed `bg` rect, the `lockup_body()` lockup scaled
46-
1.4 and centered, and the outlined tagline beneath it. It reuses `lockup_body()`
47-
(the MODERN/PYTHON crop-mark lockup in the 540×250 space) and `outline_text()`
48-
(the same font-outlining path the social card URL uses, so nothing depends on a
49-
font at serve time).
46+
`0 0 1920 240`) with a full-bleed `bg` rect, the `lockup_body()` lockup scaled
47+
`0.9`, and the outlined tagline set to its right — the pair centered as a row.
48+
It reuses `lockup_body()` (the MODERN/PYTHON crop-mark lockup in the 540×250
49+
space) and `outline_text()` (the same font-outlining path the social card URL
50+
uses, so nothing depends on a font at serve time). Because 240 px is too short
51+
to stack the lockup over a tagline, the layout is horizontal; the tagline width
52+
is measured (from `outline_text`'s returned advance) so the whole row centers on
53+
x=960.
5054

5155
```python
5256
def boosty_cover(*, bg: str, struct: str, gold: str) -> str:
53-
"""Wide Boosty profile-header banner: the MODERN/PYTHON lockup centered
54-
over an outlined tagline, on a full-bleed background. 4:1 (1920x480); the
55-
lower-left is left clear for Boosty's avatar/name overlay."""
57+
"""Boosty profile-header banner — 8:1 (1920x240). The lockup and the
58+
outlined tagline sit side by side, centered as a pair."""
59+
w, h = 1920, 240
60+
s = 0.9 # lockup visual box is x[134,406] (width 272), y-center 125
61+
lock_w = 272 * s
62+
tagline_text = "Open-source Python for production"
63+
tag_size = 40
64+
gap = 60
65+
_, tag_w = outline_text(
66+
tagline_text, tag_size, x=0, baseline_y=0,
67+
anchor="start", color=gold, letter_spacing=4,
68+
)
69+
x0 = (w - (lock_w + gap + tag_w)) / 2
70+
tx = round(x0 - 134 * s, 1) # seat the lockup's visual-left at x0
71+
ty = round(h / 2 - 125 * s, 1)
5672
body = lockup_body(struct=struct, gold=gold)
57-
s = 1.4
58-
tx = round(1920 / 2 - 270 * s, 1) # box-center horizontally (lockup box 540 wide)
59-
ty = round(200 - 125 * s, 1) # lockup center ~y200, leaving room for the tagline
6073
tagline, _ = outline_text(
61-
"Open-source Python for production",
62-
30,
63-
x=960,
64-
baseline_y=400,
65-
anchor="middle",
66-
color=gold,
67-
letter_spacing=4,
74+
tagline_text, tag_size, x=round(x0 + lock_w + gap, 1),
75+
baseline_y=round(h / 2 + tag_size * 0.32, 1),
76+
anchor="start", color=gold, letter_spacing=4,
6877
)
6978
return (
70-
_SVG_OPEN.format(w=1920, h=480)
71-
+ f'<rect width="1920" height="480" fill="{bg}"/>'
79+
_SVG_OPEN.format(w=w, h=h)
80+
+ f'<rect width="{w}" height="{h}" fill="{bg}"/>'
7281
+ f'<g transform="translate({tx},{ty}) scale({s})">{body}</g>'
7382
+ tagline
7483
+ "</svg>"
7584
)
7685
```
7786

78-
`tx` resolves to `582.0`, `ty` to `25.0`. The tagline is set in `gold`
79-
(gold-dark) on the green surface; MODERN is `struct` (cream) and PYTHON is
80-
`gold`, so the banner stays within the on-green two-ink treatment.
87+
The tagline is set in `gold` (gold-dark) on the green surface; MODERN is `struct`
88+
(cream) and PYTHON is `gold`, so the banner stays within the on-green two-ink
89+
treatment. The centered row keeps content clear of Boosty's lower-left avatar
90+
overlay.
8191

8292
### 2. Render wiring — `brand/build/render.py`
8393

8494
In `render()`, after the existing green social card block, write
8595
`boosty-cover.svg` via `g.boosty_cover(bg=GREEN_SURFACE, struct=CREAM,
86-
gold=GOLD_DARK)` and export `boosty-cover.png` at 1920×480 through the existing
96+
gold=GOLD_DARK)` and export `boosty-cover.png` at 1920×240 through the existing
8797
`export_png``_quantize_png` path. Without `rsvg-convert` the SVG still writes
8898
and the PNG is skipped, as elsewhere.
8999

90100
### 3. Architecture promotion — `architecture/brand-marks.md`
91101

92102
Extend the **Org marks** section to note the Boosty cover: what it is, its
93-
colorway and dimensions, and that it is generated by `geometry.boosty_cover`
94-
and intended for the `boosty.to/lesnik512` profile header.
103+
colorway and dimensions (8:1, 1920×240), and that it is generated by
104+
`geometry.boosty_cover` and intended for the `boosty.to/lesnik512` profile header.
95105

96106
## Operations
97107

98-
Upload `brand/org/boosty-cover.png` as the profile cover at `boosty.to/lesnik512`.
99-
Re-export at a different size if Boosty's uploader demands specific dimensions —
100-
the SVG is resolution-independent, so only the `export_png` width/height change.
108+
Upload `brand/org/boosty-cover.png` as the profile cover at `boosty.to/lesnik512`
109+
(Boosty's header slot is 1920×240, 8:1). Re-export at a different size if Boosty
110+
changes the slot — the SVG is resolution-independent, so only the `export_png`
111+
width/height change.
101112

102113
## Testing
103114

104-
- New `tests/test_geometry.py::test_boosty_cover`: viewBox is `0 0 1920 480`;
105-
full-bleed `bg` rect present; carries the lockup crops
106-
(`M138 122 L138 50 L210 50`) and the `translate(582.0,25.0) scale(1.4)`
107-
placement; tagline is outlined (glyph `<path>`s, **no** `<text>`); more
108-
`<path>`s than a bare `wordmark`; only cream + gold-dark inks over the green;
109-
no `var(`.
115+
- New `tests/test_geometry.py::test_boosty_cover`: viewBox is `0 0 1920 240`;
116+
full-bleed `bg` rect (`width="1920" height="240"`) present; lockup scaled
117+
(`scale(0.9)`); carries the lockup crops (`M138 122 L138 50 L210 50`); tagline
118+
is outlined (glyph `<path>`s, **no** `<text>`); more `<path>`s than a bare
119+
`wordmark`; only cream + gold-dark inks over the green; no `var(`.
110120
- Extend `tests/test_assets.py::test_render_writes_social_cards` (or a sibling)
111121
to assert `brand/org/boosty-cover.svg` parses and the green colors are present,
112122
and that the PNG magic bytes are present when `rsvg-convert` is available.
@@ -117,12 +127,12 @@ the SVG is resolution-independent, so only the `export_png` width/height change.
117127

118128
## Risk
119129

120-
- **Low: banner ratio wrong for Boosty's crop.** Boosty's exact cover spec was
121-
not verifiable at design time, so this uses a conservative 4:1 with the key
122-
art centered and the lower-left kept clear. Mitigated — the SVG is
123-
resolution-independent; only the `export_png` dimensions change to re-crop.
130+
- **Low: banner ratio wrong for Boosty's crop.** Resolved — Boosty's header slot
131+
is 1920×240 (8:1), per Boosty creator guides; this ships at exactly that. The
132+
SVG is resolution-independent, so a future slot change is only an `export_png`
133+
dimension edit.
124134
- **Low: avatar overlaps the lockup.** The avatar sits lower-left; the centered
125-
lockup starts at x≈770, well clear. Mitigated by the centered composition.
135+
content row starts well right of it. Mitigated by the centered composition.
126136
- **Low: PNG absent in CI** if `rsvg-convert` is unavailable. Same behavior as
127137
every other target — the SVG still generates; the PNG is committed from a dev
128138
machine with librsvg.

planning/changes/2026-07-07.01-boosty-cover/plan.md

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
> superpowers:executing-plans to implement this plan task-by-task. Steps
66
> use checkbox (`- [ ]`) syntax for tracking.
77
8-
**Goal:** Add a Boosty profile-cover target to the brand generator that emits a
9-
wide 1920×480 green-colorway banner (MODERN/PYTHON lockup + tagline) as SVG +
10-
PNG in `brand/org/`.
8+
**Goal:** Add a Boosty profile-cover target to the brand generator that emits an
9+
8:1 1920×240 green-colorway header banner (MODERN/PYTHON lockup + tagline, side
10+
by side) as SVG + PNG in `brand/org/`.
1111

1212
**Spec:** [`design.md`](./design.md)
1313

@@ -19,11 +19,11 @@ PNG in `brand/org/`.
1919

2020
- Green colorway only: `bg = #2f5e4a` (`tokens.GREEN_SURFACE`), `struct = #f4f1e8`
2121
(`tokens.CREAM`), `gold = #f0b528` (`tokens.GOLD_DARK`). No other colors.
22-
- Cover SVG viewBox is exactly `0 0 1920 480`; lockup placement is
23-
`translate(582.0,25.0) scale(1.4)`; tagline is
24-
`outline_text("Open-source Python for production", 30, x=960, baseline_y=400,
25-
anchor="middle", color=gold, letter_spacing=4)`.
26-
- PNG size: `width=1920, height=480`.
22+
- Cover SVG viewBox is exactly `0 0 1920 240` (8:1, Boosty's header slot); the
23+
lockup is `scale(0.9)`; the tagline `Open-source Python for production` is
24+
outlined at `tag_size=40`, `letter_spacing=4`, set to the lockup's right with a
25+
60 px gap, and the pair is centered on x=960 using the measured tagline width.
26+
- PNG size: `width=1920, height=240`.
2727
- All imports at module level; annotate all function arguments; `ty: ignore`
2828
never `type: ignore`.
2929
- Brand casing in prose: `modern-python`, `modern-di`. Tagline has no trailing
@@ -49,9 +49,10 @@ PNG in `brand/org/`.
4949
def test_boosty_cover(parse_svg):
5050
svg = g.boosty_cover(bg="#2f5e4a", struct="#f4f1e8", gold="#f0b528")
5151
el = parse_svg(svg)
52-
assert el.attrib["viewBox"] == "0 0 1920 480"
52+
assert el.attrib["viewBox"] == "0 0 1920 240" # 8:1 Boosty header
5353
assert 'fill="#2f5e4a"' in svg # full-bleed green bg
54-
assert "translate(582.0,25.0) scale(1.4)" in svg # centered lockup
54+
assert 'width="1920" height="240"' in svg # full-bleed rect
55+
assert "scale(0.9)" in svg # lockup scaled into the short strip
5556
assert "M138 122 L138 50 L210 50" in svg # carries the lockup crops
5657
assert "<text" not in svg # tagline outlined, not live text
5758
assert "#f4f1e8" in svg and "#f0b528" in svg
@@ -93,7 +94,7 @@ def test_render_writes_boosty_cover():
9394
assert cover.exists()
9495
ET.parse(cover)
9596
text = cover.read_text()
96-
assert 'viewBox="0 0 1920 480"' in text
97+
assert 'viewBox="0 0 1920 240"' in text
9798
assert 'fill="#2f5e4a"' in text and "#f4f1e8" in text and "#f0b528" in text
9899
assert "<text" not in text and "var(" not in text
99100
if shutil.which("rsvg-convert"):
@@ -114,7 +115,7 @@ def test_render_writes_boosty_cover():
114115
g.boosty_cover(bg=t.GREEN_SURFACE, struct=t.CREAM, gold=t.GOLD_DARK),
115116
)
116117
export_png(
117-
ORG / "boosty-cover.svg", ORG / "boosty-cover.png", width=1920, height=480
118+
ORG / "boosty-cover.svg", ORG / "boosty-cover.png", width=1920, height=240
118119
)
119120
```
120121

tests/test_assets.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ def test_render_writes_boosty_cover():
9696
assert cover.exists()
9797
ET.parse(cover)
9898
text = cover.read_text()
99-
assert 'viewBox="0 0 1920 480"' in text
99+
assert 'viewBox="0 0 1920 240"' in text
100100
assert 'fill="#2f5e4a"' in text and "#f4f1e8" in text and "#f0b528" in text
101101
assert "<text" not in text and "var(" not in text
102102
if shutil.which("rsvg-convert"):

tests/test_geometry.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,10 @@ def test_apparel_back_wordmark_plus_url(parse_svg):
8585
def test_boosty_cover(parse_svg):
8686
svg = g.boosty_cover(bg="#2f5e4a", struct="#f4f1e8", gold="#f0b528")
8787
el = parse_svg(svg)
88-
assert el.attrib["viewBox"] == "0 0 1920 480"
88+
assert el.attrib["viewBox"] == "0 0 1920 240" # 8:1 Boosty header
8989
assert 'fill="#2f5e4a"' in svg # full-bleed green bg
90-
assert "translate(582.0,25.0) scale(1.4)" in svg # centered lockup
90+
assert 'width="1920" height="240"' in svg # full-bleed rect
91+
assert "scale(0.9)" in svg # lockup scaled into the short strip
9192
assert "M138 122 L138 50 L210 50" in svg # carries the lockup crops
9293
assert "<text" not in svg # tagline outlined, not live text
9394
assert "#f4f1e8" in svg and "#f0b528" in svg

0 commit comments

Comments
 (0)