Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions architecture/brand-marks.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ gold inner symbol (`symbols.py`) chosen per repo in `projects.py::MANIFEST`.
Two-colour (green + gold); repos differ by symbol shape, not colour. The two
project templates reuse the org chevron. `modern-di-faststream` is the only
mark using a partner's literal logo path (FastStream's, recoloured); other
integration cues are redrawn evocations. Outputs: `mark.svg`, `lockup.svg`
(+ `mark-512/1024.png`). Regenerate via `uv run python -m brand.build.render`.
integration cues are redrawn evocations. Outputs: `mark.svg`,
`lockup-light.svg`, `lockup-dark.svg`, `lockup.png` (+ `mark-512/1024.png`).
Regenerate via `uv run python -m brand.build.render`.
Repos with a live docs site (`projects.py::DOCS_REPOS`, a subset of `MANIFEST`)
additionally get a 1280×640 `social-card.svg|png` — a two-panel og:image
(green mark panel + cream name/tagline/url), built with the same frame +
Expand All @@ -25,3 +26,22 @@ All generated PNGs are palette-quantized in `raster.py` (`_quantize_png`,
Pillow FASTOCTREE, `_PNG_COLORS` palette) so the committed binaries are
indexed-colour and compact; alpha is preserved for the transparent marks.
SVGs are left as generated.

### Lockup colourways and README banners

Each repo's `brand/projects/<repo>/` directory contains three lockup files in
addition to `mark.svg` and `mark-512/1024.png`:

- `lockup-light.svg` — green-ink text + gold accent on transparent background
(for light UIs).
- `lockup-dark.svg` — cream text + gold-dark (`#f0b528`) accent on transparent
background (for dark UIs). This colourway mirrors `wordmark-dark` and the
on-green mark treatment.
- `lockup.png` — the light lockup rasterized and palette-quantized; serves as
the PyPI `<img>` fallback (PyPI renders on a white background, so the light
lockup is the correct choice).

Repo READMEs embed these as a centered `<picture>` banner that replaces the
leading `# <repo>` heading. The `<source>` elements reference the assets via
absolute `raw.githubusercontent.com/modern-python/.github/main/brand/projects/<repo>/`
URLs so no asset files are committed to the individual repos.
18 changes: 16 additions & 2 deletions brand/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,22 @@ lockup** pulls them into crop marks framing `MODERN` / `PYTHON` set in **Jost**
Each repo gets a large-format mark: the constant green+gold snake-frame with
one gold inner symbol (see `brand/build/projects.py::MANIFEST`). Regenerate
with `uv run python -m brand.build.render`; outputs land in
`brand/projects/<repo>/` as `mark.svg`, `lockup.svg` (+ PNGs). These are
large-format only — every repo's favicon/avatar stays the org mark.
`brand/projects/<repo>/` as `mark.svg`, three lockup files (see below), and
PNGs. These are large-format only — every repo's favicon/avatar stays the org mark.

### Lockup outputs

Each repo gets three lockup files:

| File | Colourway | Use |
|------|-----------|-----|
| `lockup-light.svg` | green-ink + gold on transparent | GitHub light theme |
| `lockup-dark.svg` | cream + gold-dark on transparent | GitHub dark theme |
| `lockup.png` | light lockup rasterized + quantized | PyPI fallback (`<img>`) |

The dark colourway (cream + `#f0b528` gold-dark) mirrors the org `wordmark-dark`.
These are used as README banners across the org via a `<picture>` element that
references the assets at their `raw.githubusercontent.com` URL in `.github`.
Repos with a docs site also get a `social-card.svg` + `social-card.png`
(1280×640 og:image): the repo mark on a green panel beside its name, tagline,
and docs URL on cream. The docs-site repos are listed in
Expand Down
26 changes: 17 additions & 9 deletions brand/build/projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,30 +58,35 @@ def project_mark(repo: str) -> str:
)


def project_lockup(repo: str) -> str:
"""Framed mark on the left + the repo name in Jost (green) to its right."""
mark_frame = g.project_frame(struct=t.GREEN_INK, accent=t.GOLD_LIGHT)
def project_lockup(repo: str, *, dark: bool = False) -> str:
"""Framed mark + the repo name in Jost. Light = green-ink/gold (light UIs);
dark = cream/gold-dark (dark UIs). Transparent background either way."""
struct = t.CREAM if dark else t.GREEN_INK
accent = t.GOLD_DARK if dark else t.GOLD_LIGHT
name_color = t.CREAM if dark else t.GREEN_INK
mark_frame = g.project_frame(struct=struct, accent=accent)
inner = MANIFEST[repo]()
if dark:
inner = inner.replace(t.GOLD_LIGHT, t.GOLD_DARK)
name_x = _LOCKUP_H + _GAP
name_svg, name_w = outline_text(
repo,
_NAME_SIZE,
x=name_x,
baseline_y=_LOCKUP_H / 2 + _NAME_SIZE * 0.34,
anchor="start",
color=t.GREEN_INK,
color=name_color,
)
total_w = round(name_x + name_w + _GAP)
return (
f'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 {total_w} {_LOCKUP_H}" '
f'role="img" aria-label="{repo}">'
f"<g>{mark_frame}{inner}</g>"
f"{name_svg}</svg>"
f'role="img" aria-label="{repo}"><g>{mark_frame}{inner}</g>{name_svg}</svg>'
)


def render_projects(out_dir: Path | None = None) -> list[Path]:
"""Write mark.svg, lockup.svg (+ PNGs) for every repo under out_dir/<repo>/.
"""Write mark.svg, lockup-light.svg, lockup-dark.svg, lockup.png (+ mark PNGs)
for every repo under out_dir/<repo>/.

Docs-site repos (DOCS_REPOS) also get social-card.svg/png (1280×640)."""
base = out_dir if out_dir is not None else PROJECTS
Expand All @@ -93,7 +98,10 @@ def render_projects(out_dir: Path | None = None) -> list[Path]:
svg.write_text(project_mark(repo) + "\n", encoding="utf-8")
for sz in _PNG_SIZES:
export_png(svg, d / f"mark-{sz}.png", width=sz, height=sz)
(d / "lockup.svg").write_text(project_lockup(repo) + "\n", encoding="utf-8")
(d / "lockup-light.svg").write_text(project_lockup(repo) + "\n", encoding="utf-8")
dark_svg = d / "lockup-dark.svg"
dark_svg.write_text(project_lockup(repo, dark=True) + "\n", encoding="utf-8")
export_png(d / "lockup-light.svg", d / "lockup.png")
if repo in DOCS_REPOS:
card = d / "social-card.svg"
card.write_text(
Expand Down
1 change: 1 addition & 0 deletions brand/projects/db-retry/lockup-dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added brand/projects/db-retry/lockup.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions brand/projects/eof-fixer/lockup-dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added brand/projects/eof-fixer/lockup.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading