Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
befebeb
docs: add logo system design spec
lesnik512 Jun 27, 2026
09ece56
docs: resolve logo-system open decisions
lesnik512 Jun 27, 2026
1c8d7f3
docs: add logo system implementation plan
lesnik512 Jun 27, 2026
ac30841
build: scaffold brand kit (deps, tokens, vendored font)
lesnik512 Jun 27, 2026
1fd0892
build: add fonttools text outliner
lesnik512 Jun 27, 2026
2cd3651
build: org icon + favicon builders
lesnik512 Jun 27, 2026
5ae70de
build: project monogram + template-glyph mark builders
lesnik512 Jun 27, 2026
03c0fd1
build: vendor JetBrains Mono OFL license alongside the font
lesnik512 Jun 27, 2026
b152f2f
build: horizontal/stacked lockups + social card
lesnik512 Jun 27, 2026
be668c5
refactor: share icon inner-body helpers across icons and lockups
lesnik512 Jun 27, 2026
262a442
feat: generate org logo assets
lesnik512 Jun 27, 2026
793ff96
feat(brand): baked color variants and PNG export for org assets
lesnik512 Jun 28, 2026
1fc20a4
fix(brand): hoist test import, guard scratch cleanup with try/finally
lesnik512 Jun 28, 2026
56b1b58
feat: generate modern-di logo assets
lesnik512 Jun 28, 2026
024bf3a
feat: generate modern-di-fastapi logo assets
lesnik512 Jun 28, 2026
4fb453c
feat: brighten framework inks in dark-mode logo variants
lesnik512 Jun 28, 2026
ff1590d
test: hoist tokens import to module level in test_assets
lesnik512 Jun 28, 2026
749b082
feat: generate fastapi-sqlalchemy-template logo assets
lesnik512 Jun 28, 2026
856d9eb
feat(brand): widen svg() to float; emit project dark-mode lockups
lesnik512 Jun 28, 2026
f026e4b
docs: brand guidelines and adopt new mark on org site
lesnik512 Jun 28, 2026
42cf2fc
fix(brand): size stacked lockup viewBox to fit the wordmark
lesnik512 Jun 28, 2026
b606b4d
fix(brand): de-duplicate homepage hero wordmark; drop dead MANIFEST
lesnik512 Jun 28, 2026
320d1e6
chore: ignore .DS_Store
lesnik512 Jun 28, 2026
eace832
brand: verify framework colors upstream; add square org avatar
lesnik512 Jun 28, 2026
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
.idea
site/
.superpowers/
__pycache__/
*.pyc
.DS_Store
169 changes: 169 additions & 0 deletions brand/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
# modern-python brand kit

Source of truth for all visual assets across the modern-python org.
Generated files live in `brand/org/` and `brand/projects/<slug>/`.

---

## Palette

### Org colors

| Role | Light | Dark |
|-------------|-------------|-------------|
| Green (struct / frame / ink) | `#356852` | `#3f8064` |
| Gold (accent / monogram) | `#c98a00` | `#e0a300` |
| Teal (messaging frame) | `#2a9d8f` | — |
| Amber (utilities frame) | `#c2722b` | — |

Green is the primary brand color: frame strokes, org mark bands, wordmark ink.
Gold is the accent: inner snake band and gold-ink monograms.
Teal and amber are category frame colors for messaging and utility repos respectively.

### Framework ink colors

Light inks are each framework's verified upstream brand color; dark inks are
lightened toward the same hue for contrast on dark backgrounds.

| Framework | Light ink | Dark ink | Source |
|-------------|-------------|-------------|--------|
| FastAPI | `#009688` | `#2dd4bf` | Material teal / docs theme |
| Litestar | `#edb641` | `#ffd480` | litestar-org/branding (primary gold; dark = light-gold secondary) |
| FastStream | `#56b7e0` | `#82cdf0` | faststream `logo.svg` fill |
| Typer | `#475569` | `#94a3b8` | logo is monochrome black/white — neutral slate chosen |
| pytest | `#0a9edc` | `#4cb8ee` | pytest brand (royal blue) |

---

## Org mark

The org icon is two nested rounded-square snake glyphs:

- **Outer snake** — green stroke, head dot at top-left.
- **Middle snake** — gold stroke, head dot at bottom-right (counter-rotated).
- **Core dot** — green filled circle at center.

The favicon is the two-band reduction (outer + middle snake, core dot dropped).

Both icons adapt to dark mode via `prefers-color-scheme`.

**Org avatar** — `brand/org/avatar.png` is a square 1024×1024 of the mark on a
white background with padding, for the GitHub org profile picture (Settings →
Profile → upload). `avatar.svg` is the vector source. Both are regenerated by
`render_avatar()`.

---

## Project icon system

Every project icon is a **rounded-square frame** (outer snake only, no middle band
or core dot) in the category frame color, plus an inner device:

| Category | Frame color | Inner device | Ink |
|-----------------------|-------------|---------------------------|-------------|
| DI core (`modern-di`) | Green | Gold monogram ("di") | Gold |
| DI integrations | Green | Framework-colored letters (2-char initials) | Framework color |
| Templates | Green | Framework-colored stack glyph (three stacked bars) | Framework color |
| Messaging | Teal | Gold monogram | Gold |
| Utilities | Amber | Gold monogram | Gold |

**Integration vs. template distinction**: integration icons use **letter monograms**
(e.g. "fa" for FastAPI). Template icons use a **stack glyph** (three horizontal
rounded bars), representing a layered scaffold rather than a framework abbreviation.

---

## Light/dark file matrix

| Asset | Auto-adapts? | Files |
|-------|-------------|-------|
| `brand/org/icon.svg` | Yes — `prefers-color-scheme` CSS | single file |
| `brand/org/icon-light.svg` | No — colors baked in | explicit light |
| `brand/org/icon-dark.svg` | No — colors baked in | explicit dark |
| `brand/org/favicon.svg` | Yes — `prefers-color-scheme` CSS | single file |
| `brand/org/horizontal.svg` | Yes | single file |
| `brand/org/stacked.svg` | Yes | single file |
| `brand/org/social.svg` / `.png` | Light only (og:image) | baked light |
| `brand/projects/<slug>/icon.svg` | No | light only |
| `brand/projects/<slug>/icon-dark.svg` | No | dark only |
| `brand/projects/<slug>/horizontal.svg` | No | light only |
| `brand/projects/<slug>/horizontal-dark.svg` | No | dark only |
| `brand/projects/<slug>/stacked.svg` | No | light only |
| `brand/projects/<slug>/stacked-dark.svg` | No | dark only |

Use a `<picture>` element to serve the right variant in GitHub READMEs and
other contexts that don't execute inline CSS:

```html
<picture>
<source media="(prefers-color-scheme: dark)" srcset="icon-dark.svg">
<img src="icon.svg" alt="modern-di" width="48">
</picture>
```

For browsers (e.g. inline SVG on the org site) the auto-adapting single-file
variants work directly without `<picture>`.

---

## Regenerating assets

```bash
uv run python -m brand.build.render
```

PNGs (`favicon.png`, `social.png`) require `rsvg-convert` (part of
`librsvg`). Install with `brew install librsvg` on macOS or
`apt install librsvg2-bin` on Debian/Ubuntu. If `rsvg-convert` is absent the
script still writes all SVG files; PNGs are skipped silently.

---

## Adding a new repo

Open `brand/build/render.py` and add a call to `render_project()` inside
`main()`:

```python
render_project(
"my-new-repo", # slug — matches brand/projects/<slug>/
"monogram", # "monogram" for DI/messaging/utility, "template" for scaffolds
"my-new-repo", # wordmark text (used in horizontal + stacked lockups)
"my-new-repo", # aria-label
initials="mn", # 2-char initials (monogram only)
frame_color=t.GREEN, # GREEN / TEAL / AMBER per category table above
ink=t.GOLD, # GOLD or a FRAMEWORK color
)
```

For a template repo, omit `initials` and pass `"template"` as the second arg:

```python
render_project(
"my-template",
"template",
"my-template",
"my-template",
frame_color=t.GREEN,
ink=t.FRAMEWORK["fastapi"],
)
```

Then run `uv run python -m brand.build.render` to produce the six SVG files
under `brand/projects/my-new-repo/`.

---

## Font license

Wordmarks use **JetBrains Mono SemiBold**, licensed under the SIL Open Font
License 1.1 (`brand/build/fonts/OFL.txt`). The OFL covers the font files only;
SVG paths produced by outlining glyphs are unencumbered — they are not
themselves "font software" under the OFL's terms.

---

## Follow-ups (out of scope here)

- White nav-icon variant for the MkDocs Material header (`theme.logo`).
- `render_project()` calls for the remaining ~13 repos (one PR per batch).
Empty file added brand/__init__.py
Empty file.
Empty file added brand/build/__init__.py
Empty file.
Binary file added brand/build/fonts/JetBrainsMono-SemiBold.ttf
Binary file not shown.
93 changes: 93 additions & 0 deletions brand/build/fonts/OFL.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
Copyright 2020 The JetBrains Mono Project Authors (https://github.com/JetBrains/JetBrainsMono)

This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
https://openfontlicense.org


-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------

PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.

The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.

DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.

"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).

"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).

"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.

"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.

PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:

1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.

2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.

3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.

4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.

5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.

TERMINATION
This license becomes null and void if any of the above conditions are
not met.

DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.
Loading