From 8ccda2bd41791a4e05cd1277d8e89fb8e5d9fc79 Mon Sep 17 00:00:00 2001 From: Artur Shiriev Date: Sun, 12 Jul 2026 22:18:16 +0300 Subject: [PATCH 01/10] docs(planning): design for the seven un-branded repos' marks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Six modern-di integrations (aiogram, arq, celery, flask, grpc, taskiq) and compose2pod have no entry in the brand kit. Records the symbol chosen for each, verified against the partner's actual upstream logo. Three findings shaped it: arq ships no logo at all, aiogram's and taskiq's offer no pictorial glyph to borrow, and Flask's mark is a drinking horn whose Artwork License permits modified use — making a literal recolour correct and adding a second partner-path mark beside FastStream's. --- .../2026-07-12.01-seven-new-project-marks.md | 135 ++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 planning/changes/2026-07-12.01-seven-new-project-marks.md diff --git a/planning/changes/2026-07-12.01-seven-new-project-marks.md b/planning/changes/2026-07-12.01-seven-new-project-marks.md new file mode 100644 index 0000000..652bc9e --- /dev/null +++ b/planning/changes/2026-07-12.01-seven-new-project-marks.md @@ -0,0 +1,135 @@ +--- +summary: Mint brand marks for the seven repos that have none — six modern-di integrations (aiogram, arq, celery, flask, grpc, taskiq) and compose2pod — adding their symbols, MANIFEST entries and tests, and regenerating the brand kit. +--- + +# Design: Brand marks for the seven un-branded repos + +## Summary + +Seven repos in the org have no entry in the brand kit: `modern-di-aiogram`, +`modern-di-arq`, `modern-di-celery`, `modern-di-flask`, `modern-di-grpc`, +`modern-di-taskiq`, and `compose2pod`. This change mints a symbol for each, +registers them in `projects.py::MANIFEST`, extends the test set, and regenerates +`brand/projects//`. Scope is the brand kit only — nothing in +`profile/README.md`, `docs/`, or GitHub repo settings. + +## Motivation + +Every other repo in the org has a mark, a lockup pair, and a PNG fallback under +`brand/projects//`; these seven have nothing, so they cannot carry the +README `` banner their siblings all use. The gap is the whole reason +for the change — there is no broken link to fix yet (unlike the +`modern-di-starlette` onboarding, whose README already pointed at absent files), +but the seven repos cannot adopt the banner convention until the assets exist. + +Each mark was chosen against the partner's **actual** logo, verified by fetching +the upstream asset rather than working from memory. That turned up three facts +that shaped the design: + +- **arq ships no logo at all** — its README is badges only. Its mark is + necessarily an invention from what arq *is*, not a quotation. +- **aiogram's logo is a lettered blue disc** with no pictorial element, and + **taskiq's is a wordmark** whose only glyph is a tailed Q. Neither offers a + symbol to borrow, so both marks are evocations. +- **Flask's logo is a drinking horn (rhyton), not a lab flask** — and Flask's + Artwork License states the logo "or a modified version may be used by anyone + to refer to the Flask project". That permission makes a literal recolour the + correct choice, and it removes the honesty-versus-legibility tension that a + hand-drawn horn could not resolve. + +## Design + +### 1. Seven symbols — `brand/build/symbols.py` + +Each follows the existing contract: `(cx, cy, r) -> str`, bare markup, `GOLD` +fills with `CREAM` knockouts, so `test_only_allowed_colours` passes unchanged. + +| repo | symbol | cue | +| --- | --- | --- | +| `modern-di-aiogram` | `plane` | Telegram's paper plane (aiogram itself has no pictorial mark) | +| `modern-di-arq` | `hopper` | jobs falling into a hopper, one emerging — a queue being drained | +| `modern-di-celery` | `celery_stalk` | Celery's icon redrawn: banded capsule + right-facing open C | +| `modern-di-flask` | `flask_horn` | Flask's literal `flask-icon.svg` path, recoloured | +| `modern-di-grpc` | `rpc_arrow` | a symmetric bidirectional arrow | +| `modern-di-taskiq` | `task_q` | taskiq's Q-creature: thick ring, eye, crossing descender | +| `compose2pod` | `pod` | Podman's heptagon holding three composed containers | + +Two of these need explanation. + +**`flask_horn` embeds a partner's literal path.** The three paths from Pallets' +`flask-icon.svg` become a module constant beside the existing `FASTSTREAM_PATH`, +scaled and recoloured gold. The icon is a single flat fill whose bands are pure +negative space, so a recolour needs no reconstruction. This makes Flask the +*second* mark built from a partner's real artwork, which contradicts a sentence +in `architecture/brand-marks.md` — see §4. + +**`rpc_arrow` is redrawn, not traced.** gRPC publishes no icon-only asset (every +file they and the CNCF label "icon" contains the wordmark), and their true mark — +two diamonds pierced by an arrow — cannot survive our two-colour palette: the +arrow is a *different colour* from the diamonds upstream (dark slate on teal), +but our inner symbols only get gold and cream, and cream fails in the gap +between the diamonds where the background is already cream. Every faithful +rendering turned to mush. The mark therefore keeps only the arrow, symmetrized +(gRPC's own heads are deliberately unequal, sized to their unequal diamonds; that +asymmetry reads as a defect once the diamonds are gone). The accepted cost: the +mark is no longer a quotation of gRPC's logo, just a generic "calls both ways". + +### 2. Manifest — `brand/build/projects.py` + +Seven `MANIFEST` entries. The six `modern-di-*` integrations join the +dependency-injection block; `compose2pod` joins the utilities block. + +### 3. Tests — `tests/test_projects.py` + +Add all seven to `EXPECTED_REPOS`. That set is asserted equal to `MANIFEST`, and +the valid-SVG, allowed-colours, and render tests are parametrized off it, so no +other test edits are required. `DOCS_EXPECTED` is unchanged. + +### 4. Architecture — `architecture/brand-marks.md` + +The per-project section states that `modern-di-faststream` "is the only mark +using a partner's literal logo path". Flask's horn makes that false; the sentence +is corrected to name both, and to record that Pallets' Artwork License permits +the derivative. + +### 5. Regenerate — `just sync-assets` + +Produces `mark.svg`, `mark-512.png`, `mark-1024.png`, `lockup-light.svg`, +`lockup-dark.svg`, and `lockup.png` for each of the seven. Generated files are +committed. + +## Non-goals + +- **No social cards.** None of the seven ships an `mkdocs.yml`, so none has a + docs site and none belongs in `DOCS_REPOS`. +- **No profile or docs-site listings**, and no GitHub description/topics/website + changes. Those surfaces are a separate change. +- **No edits to the seven repos themselves** — the README `` banners + hotlink these assets and can be added per-repo afterwards. + +## Testing + +- `just test` green — in particular `test_manifest_covers_every_repo` + (`MANIFEST == EXPECTED_REPOS`), `test_only_allowed_colours`, + `test_project_mark_is_valid_svg`, and the render tests, all now covering 26 + repos. +- `just check-planning` passes before pushing. +- Visually inspect the regenerated `mark.svg` and both lockups for each of the + seven, and check the seven against the 19 existing marks as a set. + +## Risk + +- **Low: a mark reads as something unintended.** `compose2pod`'s three containers + inside the heptagon can read as a face. Accepted knowingly; the shape encodes + both ends of the Compose-to-Podman conversion and no cleaner alternative did. +- **Low: Celery's proportions.** Its real icon is a wide, short bar (~2.5:1), so + it fills the square frame less fully than its siblings. Acceptable — per-project + marks are large-format logos (README banners, lockups); only the *org* mark is + used at favicon size. +- **Low: Flask's artwork terms drift.** The Artwork License granting derivative + use was dropped from the Pallets repo after Flask 1.0 and nothing replaced it, + so today's assets ship with no stated terms. The grant we rely on is the + historical one, and it was explicit. If Pallets later publishes restrictive + terms, the horn is one function to redraw. +- **Low: stray colour fails the palette test.** All seven use only `GOLD` and + `CREAM`; `test_only_allowed_colours` is the guardrail. From c2472636e857fc22c30ed54ab98899278d4c2c32 Mon Sep 17 00:00:00 2001 From: Artur Shiriev Date: Sun, 12 Jul 2026 22:32:15 +0300 Subject: [PATCH 02/10] feat(brand): add the modern-di-aiogram mark (Telegram paper plane) Co-Authored-By: Claude Opus 4.8 (1M context) --- brand/build/projects.py | 1 + brand/build/symbols.py | 37 ++++++++++++++++++ .../modern-di-aiogram/lockup-dark.svg | 1 + .../modern-di-aiogram/lockup-light.svg | 1 + brand/projects/modern-di-aiogram/lockup.png | Bin 0 -> 2061 bytes .../projects/modern-di-aiogram/mark-1024.png | Bin 0 -> 7365 bytes brand/projects/modern-di-aiogram/mark-512.png | Bin 0 -> 3253 bytes brand/projects/modern-di-aiogram/mark.svg | 1 + tests/test_projects.py | 1 + tests/test_symbols.py | 13 ++++++ 10 files changed, 55 insertions(+) create mode 100644 brand/projects/modern-di-aiogram/lockup-dark.svg create mode 100644 brand/projects/modern-di-aiogram/lockup-light.svg create mode 100644 brand/projects/modern-di-aiogram/lockup.png create mode 100644 brand/projects/modern-di-aiogram/mark-1024.png create mode 100644 brand/projects/modern-di-aiogram/mark-512.png create mode 100644 brand/projects/modern-di-aiogram/mark.svg diff --git a/brand/build/projects.py b/brand/build/projects.py index c9bdb0c..390f380 100644 --- a/brand/build/projects.py +++ b/brand/build/projects.py @@ -19,6 +19,7 @@ "modern-di": lambda: sym.graph(_CX, _CY, R, dashed=True), "that-depends": lambda: sym.graph(_CX, _CY, R, dashed=False), "modern-di-aiohttp": lambda: sym.async_loop(_CX, _CY, R), + "modern-di-aiogram": lambda: sym.plane(_CX, _CY, R), "modern-di-fastapi": lambda: sym.bolt_disc(_CX, _CY, R), "modern-di-faststream": lambda: sym.faststream(_CX, _CY, R), "modern-di-litestar": lambda: sym.star_disc(_CX, _CY, R), diff --git a/brand/build/symbols.py b/brand/build/symbols.py index 0a9b95f..c89c9c7 100644 --- a/brand/build/symbols.py +++ b/brand/build/symbols.py @@ -76,6 +76,30 @@ def _sparkle4(cx: float, cy: float, radius: float, color: str, inner: float = 0. return f'' +def _box(cx: float, cy: float, s: float, fill: str = GOLD) -> str: + """Rounded square (a container / job token) centred on (cx,cy).""" + return ( + f'' + ) + + +def _ngon(cx: float, cy: float, rad: float, n: int, start: float, w: float) -> str: + """Regular n-gon outline; `start` is the angle (deg) of the first vertex.""" + pts = [ + ( + cx + rad * math.cos(math.radians(start + i * 360 / n)), + cy + rad * math.sin(math.radians(start + i * 360 / n)), + ) + for i in range(n) + ] + body = " ".join(f"{x:.1f},{y:.1f}" for x, y in pts) + return ( + f'' + ) + + def sparkle_cluster(cx: float, cy: float, r: float) -> str: """Starlette cue: a large four-point sparkle with a small companion (a "little star" — starlette).""" @@ -364,3 +388,16 @@ def tag(cx: float, cy: float, r: float) -> str: f'L{cx - 0.75 * r:.1f} {cy:.1f} Z" fill="{GOLD}"/>' f'' ) + + +def plane(cx: float, cy: float, r: float) -> str: + """aiogram cue: Telegram's paper plane. aiogram's own logo is a lettered + disc with no pictorial element, so the honest cue is Telegram itself.""" + hull = ((-0.95, 0.02), (0.95, -0.78), (0.30, 0.86), (0.02, 0.28)) + body = " ".join(f"{cx + dx * r:.1f},{cy + dy * r:.1f}" for dx, dy in hull) + crease = ( + f'' + ) + return f'{crease}' diff --git a/brand/projects/modern-di-aiogram/lockup-dark.svg b/brand/projects/modern-di-aiogram/lockup-dark.svg new file mode 100644 index 0000000..bfd20e1 --- /dev/null +++ b/brand/projects/modern-di-aiogram/lockup-dark.svg @@ -0,0 +1 @@ + diff --git a/brand/projects/modern-di-aiogram/lockup-light.svg b/brand/projects/modern-di-aiogram/lockup-light.svg new file mode 100644 index 0000000..a602b17 --- /dev/null +++ b/brand/projects/modern-di-aiogram/lockup-light.svg @@ -0,0 +1 @@ + diff --git a/brand/projects/modern-di-aiogram/lockup.png b/brand/projects/modern-di-aiogram/lockup.png new file mode 100644 index 0000000000000000000000000000000000000000..f9f61aa35ad03efd7c932a853e29eebc97a0629f GIT binary patch literal 2061 zcmY*ac{tPy7ygYg%(%8_Y*{8Gx}_gRim{I^V`)%XswqT8$&9`x+ZgIY5-}OuC2GV| zWZ$A0WnVKS+a)oXWKfc9bLV#N^F7aZ{&>%M&w1ZJ&R=hWtFxVin35O(01^)NSUdng z=z`e~4i#Wh%e!(xBe>$+Z9rd7b|PTs?fq%6aG5*OpQYK62v|@o019QSiqMe&Z2VmO z%9|I7zX0efv)HP0pbOF!@v`(%bz;qfzAX#pgGSC z!3Yc}65iPjjuP3~+Ab3o;s;B)2tTX42W;=eQ+kok!G~Y$C=5Dl;?%nUKosMEwRFEZ zwwTMkFmqI#l2!$~)A!|S{EEZ$_Ec!3cb`qZLrn2%(V-iD-g*Ar$F1%v&FMU`kli{% zSckyvOiG3Bq>ay|AjYmEL6zU9_6FJs#}cH)sg{-?Tm;5KDf~mp2ynNXem~;Q5dBR= zFsKa|`E{ZSq+(Rdzxm(V^dcDh>_A&ToMEc=w#`M*jNqJdf|>b$>rwP}>d(kqeC1gx zK~;?NgG<`@HNqL&OWULk(;gTLBaW;8NuL(np`3o3asDD{<3CB=UkRjZqw0z8-SUcF z2{SNC>?^w078Nq)SlYtG+g<)_VcqN#x@Cav*Gsoy8D&t$MEE#=(8sKSobl$#F>_M| za$P~H*$m|QCbQ14he+lh%_tMMoxkod}jivBje_(~Fxz;Wz~DYJE-qh%1&I8<=3yaM$eJ-5chKi%upVHMiE0qxKXNCWpgNoU+< zBvo2GVgHFrF@*VfY$#)1ud!}>JuRj592vCq?-6}F&Pvxf-2%Bdv}}-30dgZoWNyER zlOK}AQY(+G5CXlR@dh>aBg1Gv&(mfh`PuiVG2#H7fCP%lLR$1G-h`rpVz&E-{HGBmeZ>ou zVyi>sbyYC9>Q{fHc7;hPSa(R zKiivzBqQ9;rYu3&&eygpnf6u@gK;S-wfi+`pXWUg%dj6fy36{zh%)0?wN!$J^GunS zM^1Izs@IY8 zD#~S;%qosbPk>CMY|w~l`?F9{B9D#g^ItPpO%l>tnC*~*8Sr&-dxzffiOl%jy2w?z z%}EiCNYh+ZXS5idWX`~Mm-cy$YAZy^T&R=e!UNYt_2(zAxCge zR%e@16{GS4JVB$6y57Q2)tlq*7BI`T%WiCQF|?h0b12$J@yoRp&zApEU~z?1$rz5em-{vYF%Id%f9Xw@G$2VDAo gr_DkX{gua#=)=~&6yk;Jp8-KR*f?WLtq9b=03+(WVgLXD literal 0 HcmV?d00001 diff --git a/brand/projects/modern-di-aiogram/mark-1024.png b/brand/projects/modern-di-aiogram/mark-1024.png new file mode 100644 index 0000000000000000000000000000000000000000..5747eaa3779c73b45b7f5d9bd5895c4001b1b9e7 GIT binary patch literal 7365 zcmc&(30PCtwq7R#VJM=l8tXvlRiCra!J!Hyodm_IwN6)*q-sko4pc!@kaN`A)@lph z-d3=HV3lfX6;xCZB}XlyqJXFsWk{?-M1l-~kU%*5t$onGuYK*kefRUbFW*P@aMtjz zf9<{Y&f(J;(*oRG`?>;v`{cmaX9CEuD+6aKHi75L4`ZX7F?H4(m*U+@K7}!%GsnC? zv$6K(g{^RLE7V;5X8ht=w~owjv({&Q1>@hJX=yaIG}aIT20li^X>J|WX>>Z^xT@2U zb+e4G>=Crqs-L_wEKRk`}Aid;Mle7$x4Rw}G zS^|O~3>&s?{bysGd%g+KuVwPkGujDp|0rx8DjB)~QY?#ur(gR?5>AsAK7Z(Eb%z;dtpMOto zwD|UrL90KQLxlkhq#32$K!EGHb$*O-cz7iEJBIs(O}CKN+ubwV`MlUWUnFTDa0kGQ z82svv`5as`8NeAN9C-av1HfSd@ab4y?tC-e(*CD<`D<94xH zfV8qPe5*pQfT6R&;sMKTqjY!u_#15d0MPVv4X;*9kiIYUPRl0oU)@zhmO?Vt_LuO^ zB@QO-bf3nE$jHir2M$dCRs~;xm&@;dJ&j%w+>>hl%-%yrFvdYopy3SLWH1@F|EsSj zv(7~;zooI(V`6{s$}b`<&M<6^5DI}gn5bcE1;$HWtcJZtyMpWKOJMsZlL}@wI;0xc zT`UBi`TrIw&CSg%OkrW@dK;T#x1LVY`WxOYQp1lnt-XS=?A#!1wr4brGS0?$c9PH}J`3ahixLdN-rP*=US@X>Wb< zHDfDx7^<&O<$%}$B@@x$l>1F<7bBz#-S*v$c-tZ|R-&ERDq?Aiw;x3CPZtXb_BSl# z

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 Ut2<89`vOdUW7_M7Ue#^-Z@Bdv{r~^~ literal 0 HcmV?d00001 diff --git a/brand/projects/modern-di-aiogram/mark-512.png b/brand/projects/modern-di-aiogram/mark-512.png new file mode 100644 index 0000000000000000000000000000000000000000..586c7b4cb03415cef006899890090833555e0c9f GIT binary patch literal 3253 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 G$6o diff --git a/tests/test_projects.py b/tests/test_projects.py index c93ee6c..3d9f1fc 100644 --- a/tests/test_projects.py +++ b/tests/test_projects.py @@ -25,6 +25,7 @@ def test_project_frame_parses_and_uses_tokens() -> None: "modern-di-faststream", "modern-di-typer", "modern-di-pytest", + "modern-di-aiogram", "fastapi-sqlalchemy-template", "litestar-sqlalchemy-template", "lite-bootstrap", diff --git a/tests/test_symbols.py b/tests/test_symbols.py index 1f228ae..fe6751c 100644 --- a/tests/test_symbols.py +++ b/tests/test_symbols.py @@ -49,3 +49,16 @@ def test_msg_symbol_parses(name: str) -> None: @pytest.mark.parametrize("name", UTIL_SYMBOLS) def test_util_symbol_parses(name: str) -> None: minidom.parseString(_wrap(getattr(sym, name)(50, 50, 23))) + + +NEW_SYMBOLS = ["plane"] + + +@pytest.mark.parametrize("name", NEW_SYMBOLS) +def test_new_symbol_parses(name: str) -> None: + minidom.parseString(_wrap(getattr(sym, name)(50, 50, 23))) + + +def test_box_and_ngon_emit_parseable_svg() -> None: + minidom.parseString(_wrap(sym._box(50, 50, 20))) + minidom.parseString(_wrap(sym._ngon(50, 50, 22, 7, 90, 3.5))) From 43a2733f413aa2c1679a8164aa81d8c3d2d7f67d Mon Sep 17 00:00:00 2001 From: Artur Shiriev Date: Sun, 12 Jul 2026 22:40:17 +0300 Subject: [PATCH 03/10] feat(brand): add the modern-di-arq and compose2pod marks Co-Authored-By: Claude Opus 4.8 (1M context) --- brand/build/projects.py | 2 ++ brand/build/symbols.py | 24 ++++++++++++++++++ brand/projects/compose2pod/lockup-dark.svg | 1 + brand/projects/compose2pod/lockup-light.svg | 1 + brand/projects/compose2pod/lockup.png | Bin 0 -> 1995 bytes brand/projects/compose2pod/mark-1024.png | Bin 0 -> 8208 bytes brand/projects/compose2pod/mark-512.png | Bin 0 -> 3936 bytes brand/projects/compose2pod/mark.svg | 1 + brand/projects/modern-di-arq/lockup-dark.svg | 1 + brand/projects/modern-di-arq/lockup-light.svg | 1 + brand/projects/modern-di-arq/lockup.png | Bin 0 -> 1544 bytes brand/projects/modern-di-arq/mark-1024.png | Bin 0 -> 5789 bytes brand/projects/modern-di-arq/mark-512.png | Bin 0 -> 2483 bytes brand/projects/modern-di-arq/mark.svg | 1 + tests/test_projects.py | 2 ++ tests/test_symbols.py | 2 +- 16 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 brand/projects/compose2pod/lockup-dark.svg create mode 100644 brand/projects/compose2pod/lockup-light.svg create mode 100644 brand/projects/compose2pod/lockup.png create mode 100644 brand/projects/compose2pod/mark-1024.png create mode 100644 brand/projects/compose2pod/mark-512.png create mode 100644 brand/projects/compose2pod/mark.svg create mode 100644 brand/projects/modern-di-arq/lockup-dark.svg create mode 100644 brand/projects/modern-di-arq/lockup-light.svg create mode 100644 brand/projects/modern-di-arq/lockup.png create mode 100644 brand/projects/modern-di-arq/mark-1024.png create mode 100644 brand/projects/modern-di-arq/mark-512.png create mode 100644 brand/projects/modern-di-arq/mark.svg diff --git a/brand/build/projects.py b/brand/build/projects.py index 390f380..f73336a 100644 --- a/brand/build/projects.py +++ b/brand/build/projects.py @@ -20,6 +20,7 @@ "that-depends": lambda: sym.graph(_CX, _CY, R, dashed=False), "modern-di-aiohttp": lambda: sym.async_loop(_CX, _CY, R), "modern-di-aiogram": lambda: sym.plane(_CX, _CY, R), + "modern-di-arq": lambda: sym.hopper(_CX, _CY, R), "modern-di-fastapi": lambda: sym.bolt_disc(_CX, _CY, R), "modern-di-faststream": lambda: sym.faststream(_CX, _CY, R), "modern-di-litestar": lambda: sym.star_disc(_CX, _CY, R), @@ -39,6 +40,7 @@ "db-retry": lambda: sym.db_retry(_CX, _CY, R), "eof-fixer": lambda: sym.eof_fixer(_CX, _CY, R), "semvertag": lambda: sym.tag(_CX, _CY, R), + "compose2pod": lambda: sym.pod(_CX, _CY, R), } diff --git a/brand/build/symbols.py b/brand/build/symbols.py index c89c9c7..13072d4 100644 --- a/brand/build/symbols.py +++ b/brand/build/symbols.py @@ -401,3 +401,27 @@ def plane(cx: float, cy: float, r: float) -> str: f'stroke-width="{r * 0.11:.1f}" stroke-linecap="round"/>' ) return f'{crease}' + + +def hopper(cx: float, cy: float, r: float) -> str: + """arq cue: jobs dropping into a hopper, one emerging — a queue being + drained. arq ships no logo, so this is drawn from what arq is.""" + jobs = "".join( + _box(cx + dx * r, cy - 0.72 * r, r * 0.34) for dx in (-0.52, 0.0, 0.52) + ) + hull = ((-0.86, -0.30), (0.86, -0.30), (0.20, 0.34), (-0.20, 0.34)) + funnel = " ".join(f"{cx + dx * r:.1f},{cy + dy * r:.1f}" for dx, dy in hull) + return ( + f'{jobs}' + + _box(cx, cy + 0.76 * r, r * 0.34) + ) + + +def pod(cx: float, cy: float, r: float) -> str: + """compose2pod cue: Podman's heptagon holding three composed containers — + both ends of the Compose-to-Podman conversion in one shape.""" + return _ngon(cx, cy, r * 0.98, 7, 90, r * 0.15) + ( + _box(cx - 0.34 * r, cy - 0.20 * r, r * 0.36) + + _box(cx + 0.30 * r, cy - 0.20 * r, r * 0.36) + + _box(cx - 0.02 * r, cy + 0.30 * r, r * 0.36) + ) diff --git a/brand/projects/compose2pod/lockup-dark.svg b/brand/projects/compose2pod/lockup-dark.svg new file mode 100644 index 0000000..f5b1bae --- /dev/null +++ b/brand/projects/compose2pod/lockup-dark.svg @@ -0,0 +1 @@ + diff --git a/brand/projects/compose2pod/lockup-light.svg b/brand/projects/compose2pod/lockup-light.svg new file mode 100644 index 0000000..0850ba6 --- /dev/null +++ b/brand/projects/compose2pod/lockup-light.svg @@ -0,0 +1 @@ + diff --git a/brand/projects/compose2pod/lockup.png b/brand/projects/compose2pod/lockup.png new file mode 100644 index 0000000000000000000000000000000000000000..43b5e2ca3caea21848625687d2d7e465940ea6f8 GIT binary patch literal 1995 zcmV;+2Q>JJP)|fPht1 zRWoL0ELmC6l>jktP(WZ{K!8C1fB^sh0Kb3$s;U400000000000)v^5D0000WbW%=J z0R8@jgUu~XZWFB)G0N?3fcjgTvR1U*5gsTb#<@XD(fpFweWJK0Wod_~4Nd{?y zAVcJeT#+j>M6Spcxgta4id>N^GMwQ`F^~Nct_15YKg$&bxguBOih^8`D{@6auE-U+ zq9E7b$hB#a>jc;4@KTUNGmG`GL$2doZ$+#<*xMY|7vws@b@wtNyE&}Lb%N_rtLAYa zT8WP{Sdr^E*S*%v{qo-vn~Yq?xHcM3(XF@oOf&83kn0H7+r-nn8~0s4f)t<@&3lh3-vcbtlMe>>Oy9rhNkGrno$JV+z{ajs1CFYUSfZmz~> zO~q1WeFka7;h(0e+`5JQR<5@N5$LXv&^`%Q78kDMcXFNbSzi7WeAn*f8SH>Gn#vd_ ze^GJT!ZkkQZD+(=grhxd$9&gwaP8MkW!SyLzKtvJNuJU^p3w3+;=7)L>j}Uln-z9F zSD0scN^Q!u8S!0D!Ic3dYy!`tx$Xd!X|74rr{T)Ma^*L3y)EN<+s0KgE|S<$A4fZP zmHj!{|8&(y7jW((^{K1=kteed4Jv?i{5DgeKl#5l=tCPgNfO$>@VxN z9s#%+u1)5-7IBqsT1w!e*tlZ>Azg;U|^{zI~hZT=$@iHN&;d9M=-AEZaXTRUS2OOfPe-sV;(5vn5f^h@?W^rTmht#8eY)-!iKze{~g+<=5#q*gWhnnni7ubkF? zTGZd3lbIN^6H_NRRIkT$L!8ycY-ztU;?=iJ4|RUkt&6kHdbQRzN=2*+I5m>gsfzNN z7Dx#a&1KZ~XG{h4YJ66}um%7!aCNrE_Yx<@+{EHgujbaT<$9c| zWaU+a<2tUqj`g*3zuq$lCbee0I(_p?RQ`EYo-0pV3ovA< z#5zf`R;c?aannm-VsI$Ar9P0GO`BK^X?Jt+oR)v#$a|p0xuiyCtz?R+0lnd`v3F5oI*_~IUV5}B)Nma94^D`OG0>$^|jSbUx(I8R-7 zGRIm0mnQ2Fm5>NZrFWIpo4Dr0%3KHTZArdmqMJ8cCh+NyaWJNAz~;Hy1U|MVj>Cz& zb@+hZ)l`U&?|lMhf=``DISKiexcFP=(UHN#YTjpF7n9F!;CdXXt9CQt*aEI5J*<_Y zHO!%?Id+fPwBL%YUG8IjzX}BbGXf>b^(T!7v*(q*p?5m`c$(UdK`*6=$vD)M9RU5) zYSJUMN%>{WyDh9|iLA`R!aP_t&sDHIWV!_XAl6b}Nm4+$hWd#(2RK8nCz8KP3=<3W znouJm=S^G(5tPjfKBuFxrS(@SR3D^=s$TyD>tn^=;{VV&;>0%+M8uF)U#{RAYDx4j zpbW@JGJrYsR}B8;E|_ALPD@8?c4DB`YrE3^l86O%AP+^l1uv?H=Jm_p7x3KQR1ez~ zRDZ?(ELPn4+J1~*`_Yzm5+T=wD=Tjk>dF2oU-_p!yp%Q)Ay>$ijcnC6yR{1i!{&G> zmJ5(;!nM3Hq4A7%x16d!(NxHFoa^X*kIxdoDXPd7aAlJpw;fW5L5Yve-1js8bFMSH zlWv}Dw~tg0$6HnX2v@s*;0wg=A9x(s`AuK%L1#VH_Pwfph->vE-xn;~OSkX9w$`bj z7P;EwaPbyJPqy37?=?oQYebXnW?#}G*Y(mY*iwL8zebQNaz(Bv$Q8LFR}|!mT#@T< zk{15^P>Wn2CE4FPEtCUtUBz{SAXnsyT#+ksMXtydxguBOid>N^a(!SP3#3JckE^?& dprAaH{0I6WOrw(70J{JH002ovPDHLkV1f+G&Ab2r literal 0 HcmV?d00001 diff --git a/brand/projects/compose2pod/mark-1024.png b/brand/projects/compose2pod/mark-1024.png new file mode 100644 index 0000000000000000000000000000000000000000..90d53fe543be18f143ac2061bf47b3ae6655fcf0 GIT binary patch literal 8208 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 diff --git a/brand/projects/modern-di-arq/lockup-dark.svg b/brand/projects/modern-di-arq/lockup-dark.svg new file mode 100644 index 0000000..ed076c9 --- /dev/null +++ b/brand/projects/modern-di-arq/lockup-dark.svg @@ -0,0 +1 @@ + diff --git a/brand/projects/modern-di-arq/lockup-light.svg b/brand/projects/modern-di-arq/lockup-light.svg new file mode 100644 index 0000000..7589a9a --- /dev/null +++ b/brand/projects/modern-di-arq/lockup-light.svg @@ -0,0 +1 @@ + diff --git a/brand/projects/modern-di-arq/lockup.png b/brand/projects/modern-di-arq/lockup.png new file mode 100644 index 0000000000000000000000000000000000000000..695098fc88c328a7b84417c442877b9fdb7b0bcd GIT binary patch literal 1544 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 literal 0 HcmV?d00001 diff --git a/brand/projects/modern-di-arq/mark-512.png b/brand/projects/modern-di-arq/mark-512.png new file mode 100644 index 0000000000000000000000000000000000000000..bdc64f81e67f5ba832026ab9f80ae2e77180d709 GIT binary patch literal 2483 zcmchZ2~bo=8i4;dC-*=I5#^ZiKyl*{6-5M`$KgQ;0|HSOAxw#)sIaIA!x862i$ehg zL&WS-G6dEuvS8$r^Rc)bF~|T~BF8c&QXDc2g3bVs_uf9LOjW9~yR}<;{MGgSfB*gW zU)^0@fA!s_DjxRz^wvJ_+2x=(Y>6`KW(;3T!wL zxL`*Fv|U_qwlcg34oCbMG676$z@Q@sXd3R^0fz<89vTA_Ls6-8T}TL%>erHe@yN%F zR}|wf2>^?kE>s1f*o$A|S znY_o(=!f%*4^(_vrlE^`oV&k{U0JdEN&(Ejs(F@No;!5j^CLU2D=QY7!C+JOGoLzF zSJ~8(Yjoe?#89(abvGZ?Uw29VR2TceR7J@5UB2FYj5y`=jo3B&q#Oe0JXGn_XcoDC z@Lc`W=wLmV*6`t=PVd({`Tu%?`yC9h^uA^ru4=U4w(a^T>*q7a2UdOV%E7ImTx&YL z3ShLgW|!Cw?xdOqN7cM3R*)LVZ9)z`?*2 zSSaWL^55)WqM;9=K&MFncZ~p@BoV!OF*NGP@;b-(sTHN;}AOH~?q048TCaf3yu zqlUg;8&3;tgPSR1*kA7MSU)}2FxL2}B(#+{BRIP@p60=tZ^LE7hBh@eNqe`;?BnS< zRvXAhUYcO7aEgx}f(LBT#(z6Zs!lzO95u&#$pwxvd=H;v zXoedTY^4Z0pyexE!BMU0Dz&k?8XwUUNz`mDJ3juS(n=Q>FAK{}9junWVK19&Hc6|B zm+yKQv)0D!G(oKeS;)!VPfn+Ke6wX-bFC_WRh>_tZ$ct9ey!^G3&PocV|hHa9JG9# zf*$&Qzhh};b1`g$zb{$6^uAKvLgo19g0bL@$ELSXv`MV>3%b7#Q?ho7S?-3Gq={(| zK9Y+weL1%%;4yD)S!4be1zaOazznE_ZVRTlY`CPdll-Y}QI=Xb->xv=9{L?G`Gc%F zE6X5M8ykHTc|MF>DhVAI66S8@dNX94aoSvV={C-q&sm~U%v>v&FHlZ#^X|!C`f_vE zsd7jU`I_2%CcGNE!u_N}AH!KUwj-wd@t8A*l}>e%d%Czt)hlb=uo&bz|2%9qaUsvF z9g-!9jGCMB1%IDK#_f;!RV|2FSa+@*@yo^OLWK2G*-w5bu1jpG+}3qF+T&(Elk;>iDYbEQ1~)=KPsM zS+F^92OY-Z4DDYKLhN$2#3z{2N3%Z1qL633ha^-Et3>A{G)kFF7a)72*&lM9IR6JN8MS43YMk zUp0qf=$XnG;-JnDRWFmZ>0?)+%;FziB3uH31BlCF9w5K0NwfP(m++-@4~z?~Ffxo? zDn9|*%f>i$59twa!M@jaG|fbL@KoV&MlDV{_4Uj~P)<_EqgHHa0Oh!j4j%5rxop|d z*Ks$E(830~ee+*!iVi_JNmfqfDY)29nhGTx5akFhhpq3S$u!MYp|F{v7hyj^;4I@c zVfzgeVzA~ax^y&b)kBLlG%MN&J2pu3Ri^OvEXBr_L*V?Z5KO>tdbk041d6c^8Y#6x z2l8o-bUoI>VM@eT8UeG%a)#UCDZ_Q}mZ2>ej|*@USj#XLd>Dp9B*VRs$#5qWGu#60 z3|E4h;Rj%>*7V}W5Y#*Pw6T&c%aB!EnMRfji2oST{-uM{(xRtiK!ZE}gsmK-R)>hm z&C=R!c6SFzdgVtM(>0kM`PSyo-cS;Q5W{z82t*6-7Y7_or}hBnfAc^90;oN7G}WG% zOUR9o@e~Qr)TKU}geZ diff --git a/tests/test_projects.py b/tests/test_projects.py index 3d9f1fc..cbf0a02 100644 --- a/tests/test_projects.py +++ b/tests/test_projects.py @@ -36,6 +36,8 @@ def test_project_frame_parses_and_uses_tokens() -> None: "db-retry", "eof-fixer", "semvertag", + "modern-di-arq", + "compose2pod", } diff --git a/tests/test_symbols.py b/tests/test_symbols.py index fe6751c..c784137 100644 --- a/tests/test_symbols.py +++ b/tests/test_symbols.py @@ -51,7 +51,7 @@ def test_util_symbol_parses(name: str) -> None: minidom.parseString(_wrap(getattr(sym, name)(50, 50, 23))) -NEW_SYMBOLS = ["plane"] +NEW_SYMBOLS = ["plane", "hopper", "pod"] @pytest.mark.parametrize("name", NEW_SYMBOLS) From 13bdffe3f3334639ad662f8483a9fed7a898e8e8 Mon Sep 17 00:00:00 2001 From: Artur Shiriev Date: Sun, 12 Jul 2026 22:46:39 +0300 Subject: [PATCH 04/10] feat(brand): add the modern-di-celery and modern-di-taskiq marks Redrawn from measurement: celery's icon has no SVG source (celery/celery#5981), so celery_stalk reproduces its banded capsule + open C, measured off celery_512.png. taskiq publishes no icon-only mark, so task_q reproduces the tailed-Q-with-eye glyph from its wordmark. Co-Authored-By: Claude Opus 4.8 (1M context) --- brand/build/projects.py | 2 + brand/build/symbols.py | 45 ++++++++++++++++++ .../projects/modern-di-celery/lockup-dark.svg | 1 + .../modern-di-celery/lockup-light.svg | 1 + brand/projects/modern-di-celery/lockup.png | Bin 0 -> 1751 bytes brand/projects/modern-di-celery/mark-1024.png | Bin 0 -> 5941 bytes brand/projects/modern-di-celery/mark-512.png | Bin 0 -> 2360 bytes brand/projects/modern-di-celery/mark.svg | 1 + .../projects/modern-di-taskiq/lockup-dark.svg | 1 + .../modern-di-taskiq/lockup-light.svg | 1 + brand/projects/modern-di-taskiq/lockup.png | Bin 0 -> 1947 bytes brand/projects/modern-di-taskiq/mark-1024.png | Bin 0 -> 8289 bytes brand/projects/modern-di-taskiq/mark-512.png | Bin 0 -> 3590 bytes brand/projects/modern-di-taskiq/mark.svg | 1 + tests/test_projects.py | 2 + tests/test_symbols.py | 2 +- 16 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 brand/projects/modern-di-celery/lockup-dark.svg create mode 100644 brand/projects/modern-di-celery/lockup-light.svg create mode 100644 brand/projects/modern-di-celery/lockup.png create mode 100644 brand/projects/modern-di-celery/mark-1024.png create mode 100644 brand/projects/modern-di-celery/mark-512.png create mode 100644 brand/projects/modern-di-celery/mark.svg create mode 100644 brand/projects/modern-di-taskiq/lockup-dark.svg create mode 100644 brand/projects/modern-di-taskiq/lockup-light.svg create mode 100644 brand/projects/modern-di-taskiq/lockup.png create mode 100644 brand/projects/modern-di-taskiq/mark-1024.png create mode 100644 brand/projects/modern-di-taskiq/mark-512.png create mode 100644 brand/projects/modern-di-taskiq/mark.svg diff --git a/brand/build/projects.py b/brand/build/projects.py index f73336a..eb4316d 100644 --- a/brand/build/projects.py +++ b/brand/build/projects.py @@ -21,11 +21,13 @@ "modern-di-aiohttp": lambda: sym.async_loop(_CX, _CY, R), "modern-di-aiogram": lambda: sym.plane(_CX, _CY, R), "modern-di-arq": lambda: sym.hopper(_CX, _CY, R), + "modern-di-celery": lambda: sym.celery_stalk(_CX, _CY, R), "modern-di-fastapi": lambda: sym.bolt_disc(_CX, _CY, R), "modern-di-faststream": lambda: sym.faststream(_CX, _CY, R), "modern-di-litestar": lambda: sym.star_disc(_CX, _CY, R), "modern-di-pytest": lambda: sym.bars(_CX, _CY, R), "modern-di-starlette": lambda: sym.sparkle_cluster(_CX, _CY, R), + "modern-di-taskiq": lambda: sym.task_q(_CX, _CY, R), "modern-di-typer": lambda: sym.terminal(_CX, _CY, R), # templates — reuse the org chevron "fastapi-sqlalchemy-template": lambda: sym.chevron(_CX, _CY, R - 1), diff --git a/brand/build/symbols.py b/brand/build/symbols.py index 13072d4..5a7bf1b 100644 --- a/brand/build/symbols.py +++ b/brand/build/symbols.py @@ -425,3 +425,48 @@ def pod(cx: float, cy: float, r: float) -> str: + _box(cx + 0.30 * r, cy - 0.20 * r, r * 0.36) + _box(cx - 0.02 * r, cy + 0.30 * r, r * 0.36) ) + + +def celery_stalk(cx: float, cy: float, r: float) -> str: + """Celery cue: their icon redrawn — a banded capsule with the pale open C + at its right end. Measured off celery_512.png; Celery ships no SVG (see + celery/celery#5981), and the C is *open* (facing right), not a closed ring.""" + s = (2.35 * r) / 512.0 + body = ( + '' + ) + bands = "".join( + f'' + for y in (205, 256, 307) + ) + arc = ( + '' + ) + return ( + f'{body}{bands}{arc}' + ) + + +def task_q(cx: float, cy: float, r: float) -> str: + """taskiq cue: the Q-creature from their wordmark — a thick ring with an + eye and a descender crossing it. taskiq publishes no icon-only mark.""" + ang = math.radians(48) + dx, dy = math.cos(ang), math.sin(ang) + ring_y = cy - 0.06 * r + ring = ( + f'' + ) + tail = ( + f'' + ) + eye = ( + f'' + ) + return ring + tail + eye diff --git a/brand/projects/modern-di-celery/lockup-dark.svg b/brand/projects/modern-di-celery/lockup-dark.svg new file mode 100644 index 0000000..c9fb754 --- /dev/null +++ b/brand/projects/modern-di-celery/lockup-dark.svg @@ -0,0 +1 @@ + diff --git a/brand/projects/modern-di-celery/lockup-light.svg b/brand/projects/modern-di-celery/lockup-light.svg new file mode 100644 index 0000000..319523f --- /dev/null +++ b/brand/projects/modern-di-celery/lockup-light.svg @@ -0,0 +1 @@ + diff --git a/brand/projects/modern-di-celery/lockup.png b/brand/projects/modern-di-celery/lockup.png new file mode 100644 index 0000000000000000000000000000000000000000..45981eebc3d75bc9cdc0db0783ebd360098282d8 GIT binary patch literal 1751 zcmV;|1}OQ7P)-Qpt({HD^-Di2yZd zQZ;B$G-y&aXi_w1Q8i~$$cX^WlNH{(Z|>vCGiGMVi2%xm0LY2}69BIS0000WbW%=J z3I!wr1pohh3;!qq3;_N9hk?%%ZBVc<&HexW1*;fIXO0Xn000ICNklwyiwv;fluzo^XB2r;ocG- z0RQs)^?I&|>*;j8Uf-V*UUuhgwgvxA0IMR%pN>z|)pY;zO||&j^>}Zbo)La8w$;bq z&Ud>XuTKfTtx?U({q4Pr8{oeP|JT2@@#jdB2mEaKKYrFm-sE3u;aedt`&LQczZ#{o zk%j2?m<(9-hqM{|&h$r-5?}Ym6)1#oWsF@TO#a?Bdrjf96uOd{{#3-P zNM$xchr9z#C_y5r`Kcjs*af@(Ca+Tm)$-}l-qCKi}==RuQA}zv) za_`b2!goa!KMP(YlpJ1bQ^JQ7Wc>2FOF@w#YPUhw!=GltAMbz<^)eG4i+GLu!WN&s ziCbiV7rMy0dzWS4jfD?|=)qD?D0&KB72o`K&4N4$5a1hyZM|u2s)oX|z7pY5kl~VbDKKR-Zek0&qmTdjRvABf-5+mnzs-OT zfX+tw)@dSE->A7i#`i<^dI^7Y8=)GvE4FSPCPgxD@}z8j7>Dn7u-4bl91n{*YXYz0 z%*&*tc)AbBkc!zDJPSYAKG~!k`oxRN+K{;=^XJIZ4={6>lJuqVY(=h0$`%vw^is9T zm2gSLiUh9{sjpilLE}p`gU;@ox|-V^H`jfh8MjZdwOtx5>26t0Djd8Z=i^UTl3sPh zh<*4ws3b=f@X8&i=;hiMH&=IvF0Pd8+(=C_!i#(d_oEte!L+@#^1H_I4;fC5!mDib zW%JJFOzwrspZDaS!21zVc2NuXP*5pVJXy*jycwoI;al56z|EYdWn36m<~Bi$gs241>}ZJck7jpNB| zUolsLue{Z61;WFVsgZJX>>OTv^kM31AB0T9_k(wP8u^S+ia2{0VHhsLLW-$`Z$jCP zJWRmbE23IgGV_(&*Zm5TZ4w@Sm_iP3=Z0o$AN@_kyGbS2nj~aX)@Ai2mJIWPh;?lxdT2eqgKE#=MMPkPo9SG3%Uc| zEl!#m_$A!|pRX@{1iz>|;Qd!@K8Ih{9q_f^BwN@W@OAKVX?MV{^>?5E4|u>M01tS; z10L{z2Rz^b4|u@;;_&Zd-&X?s_rn)o(W{Iz;FpD;{iFf{@PG$A-~kVKzyluefCoI_ t0l%pw0}}Y-ERS3yL#(tci~#&r<3CWd!pdjCV^jbD002ovPDHLkV1fsgXI=mR literal 0 HcmV?d00001 diff --git a/brand/projects/modern-di-celery/mark-1024.png b/brand/projects/modern-di-celery/mark-1024.png new file mode 100644 index 0000000000000000000000000000000000000000..08801b15eaaa59b61a29953f8e221d6271905ad5 GIT binary patch literal 5941 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 N0)rNPvXFoE{{X3)_qG54 literal 0 HcmV?d00001 diff --git a/brand/projects/modern-di-celery/mark-512.png b/brand/projects/modern-di-celery/mark-512.png new file mode 100644 index 0000000000000000000000000000000000000000..7008e573063f15ab7e329214ad2e5fde9f03af68 GIT binary patch literal 2360 zcmdT_eN>ZG7=PY(>=U*@Ff?Ioew0KWm^E@Lu~&|OXyD{SEFe~COi{!H6$AF-M+jHcwl&%O8go%7t^ zz32Dj$ijlztQjl-V23PQ8V-QkLKGMj8#I*6X|jP__C{o&uOfVG>|V=J*XleVNf_D( zVnw+Ac5&y02w%l24976JeC(%z>xY=$ad9@%wOn{gd8EIV11%rH{Ed;m>m%+~uY1_n z)Rg=5RGbiQOZY8r%7J4G3)5^gVM=&d#3nXLMQF!Kve}N&QDP5Pt5xjc;zwGmRs`0x zZ8}5^-mwLMkr1+UN#u?@qq>;wx7*RZt9FmNc%FZ-{K~SNVv_V37P0os|DgVpCb_{^ zqko)y%lD$UTCr7@;zlyT5l{>mfC#}3hnvN>`;%5LC~yYe4bm#neB}(q8h?-cOGwc` z(#MTMRCqLOwe)Vc$1Y|ps%-0p`yQ}d!tgVah9l}Po2`u#-ymxSxgBH%DztICbWbJx zPe(BKAW95e+>(fN7M>e24b&fw`no+%r}Kg&@Vpdp)d}#13mH4d`oVUkE9F)IZIz`a zQrkj@=A^0tl(@V{$f)3~ zT4c|6%7sh1k>rJ@m7yCckbRa}nMc1l9-0y-!Ot=`@1vG*36op%=3=|2OczUWQ2!%+D8e1+xRuosTbq9moj_|Evw2<)#%F54I(tt?FqqDj3if z4Sx+4O7X|NPG2C}_NLa;wAEa>$T;;L#s+u9)t#~dh#B(wRE!GU)SYE;vV*FtRjg{atG{Zgzy{&iMC(nO}VO> z{$u$&p{D4DLOXF+JSWvhWEsAfL~W5$A34v@ob_$q(w`4|N}W5*CnZvs!R%R<$c=ra z?^@P;DcEn?`ctNN4`uebG^8`g@0I?(;JgDNnQISZ2eo9r>i`~ZbetZH5^WdP#Z&8Q z3_kj)GH#y9Y;NSj-FeXCTx$i{G}z3HO{2>A_^Flq;Vy}iP%wTHfpmP{su zC6Lx5NVkULaBQYzWuLj}-licA_~jJwOV#N#eddfi56g$MmEqED7sh+m9|rZ3fja@i zwR8Q4t2I+0xM_`+!)BEiwX;<2Ny%G%{o3^H_nF_C<6t><1x@o6}@)706bl> zj*3?zLL*WAS zyn_@%c6Imc#To0P-SI8QEae~W9NW3h&#(5?lrmUd!y7g`C diff --git a/brand/projects/modern-di-taskiq/lockup-dark.svg b/brand/projects/modern-di-taskiq/lockup-dark.svg new file mode 100644 index 0000000..b929362 --- /dev/null +++ b/brand/projects/modern-di-taskiq/lockup-dark.svg @@ -0,0 +1 @@ + diff --git a/brand/projects/modern-di-taskiq/lockup-light.svg b/brand/projects/modern-di-taskiq/lockup-light.svg new file mode 100644 index 0000000..4da500a --- /dev/null +++ b/brand/projects/modern-di-taskiq/lockup-light.svg @@ -0,0 +1 @@ + diff --git a/brand/projects/modern-di-taskiq/lockup.png b/brand/projects/modern-di-taskiq/lockup.png new file mode 100644 index 0000000000000000000000000000000000000000..a33093af09e29063fdf8e08d6cebf1e749946cd4 GIT binary patch literal 1947 zcmY+Fc{J2}AIHbm+-Tgyj1scO6q-f0(amGYGK`Q*WteQEEK?@QQl{=zjjXLR*)Ec! zY^@ApEHT5+k~qRdS$^Xgiu^E1nrEDI@AI7JoX>fGzVFZX{r>yKJW6s#C~7FeU@(NM zi=#ITCPSCLLw}KzssmTYQo1Nd-H$mr2L#OAguxgLe0ccE(tI-mCXvAG7T#fEK;07)U9+JK_qhIX5C+@Qkk;6q6}QI#=t?TlcQ%FfQExVJ*k6c)UoDP_w+=fRa3+iW5}OOs`Ur}dQ#^ypdAT z&uc<7-dH0~$LH8gkKu(9C2%FdUUYi8nw#hKtiZY`$^rDSibln~8+5WN%Jg{HveI2m z?Ioc#k^n-{pV6HH>dgH_gA7iS4gCkKssWh!qb(OJjtSJvs#{+5Bv?uo)`h}3EB8Is2YLhk3?3j9U-Ox?9x*BKQyw4A%I;IC8M=w@gLle) zZSFalM_6bwgsOAO-pWGJ>>#c8O@$4e=M=y(oLFYsI6GxeXDdk&O3!vE@QP~HDLHqU z*p5U!HGD=yVJGk-`}@D;;48DY7ssU^(tb3i1!c;=w$WqfqU_sb1V;K`z6LS<{hLQ$ zGLTvL2?g}TR|v9tu;a@P7BRP6>-OEH-Cs;X1+1wPH!Pk#EJ(OU90ScC2g=^6D~{zJ zO^plLK$A4-MXf<*8##%Qsao706+JJ29Dbr(yy9Wp!PJCO zhMZFA^gl#3Y0cGO>^z|B*tEAatUybm?m*8XjZeLOoh98IDmNguEt&~o@IcqOYmP;VsPD!!;In!`~bbf(<<~) zd|cT0z)7o$;ThAIacZyX%Mmt4UnxfYjX5)%Br6%pFP`sd9{RejWkxMZ0O5Lcqjx$J zD!s+;FWRq<-!R5pEyXpbBY)f1W%*=@?#wIWCw84GLc&u~sgb)zTYTS}2k&*$Toz%= z>h%$Y$HsFV;?%V}P=|>6>pWyQk&JJid96|+(!~}uvPsjwsIm@*vgTIhPx&YlSfLW6pov-ZR5)_&xp zYHk=lZQrF_K>V+tmpd}Bsn6qf*@*o@7!W65~_pf8lzx(&a z-u(L6o)CdB&4lN8$(H(Q@ODR|c1#OkPJCGO;eoK~J=edL*^&4_$wq(VhsM_jKk3%L-RSoP!n~_M z^rYrGIu!%ozc zLU_55(o-8=MQpzXadpCi`G#0Rk@xU)q~ti5`02=80l&}JA`KIpptM@JysAoQsXupT zMDQRnD`A%~plvqx(sIok8?a>wnMvG!e41l$Z57pu!iwv$>~dzs<#A7K-_NH%*M3>( z7$NvHAOT3^HLJvG$Pc`lO-^^>1tH6Kcaph^-Kg)n5)pc9uHYILv6_jEZP6}j;o*!z zFH_QZIAq_p-<0EDUx}dPlDJLknM}Aye_S&FK z#+i>IrzG|Ln4qp?(A`~Co86$65%<#q4weJznhs}1C-*&!*xhG=rOAM<&a3T$L@iS$ zV+{wIxXzutEe9O~qu#YJIHW9t6X4);eqf6q4M WUlDb6!D>gJT#I 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 literal 0 HcmV?d00001 diff --git a/brand/projects/modern-di-taskiq/mark-512.png b/brand/projects/modern-di-taskiq/mark-512.png new file mode 100644 index 0000000000000000000000000000000000000000..006bed6f0ad9d75b307329a3d8854971a58003c2 GIT binary patch literal 3590 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 diff --git a/tests/test_projects.py b/tests/test_projects.py index cbf0a02..cf2c6e1 100644 --- a/tests/test_projects.py +++ b/tests/test_projects.py @@ -38,6 +38,8 @@ def test_project_frame_parses_and_uses_tokens() -> None: "semvertag", "modern-di-arq", "compose2pod", + "modern-di-celery", + "modern-di-taskiq", } diff --git a/tests/test_symbols.py b/tests/test_symbols.py index c784137..e0d0113 100644 --- a/tests/test_symbols.py +++ b/tests/test_symbols.py @@ -51,7 +51,7 @@ def test_util_symbol_parses(name: str) -> None: minidom.parseString(_wrap(getattr(sym, name)(50, 50, 23))) -NEW_SYMBOLS = ["plane", "hopper", "pod"] +NEW_SYMBOLS = ["plane", "hopper", "pod", "celery_stalk", "task_q"] @pytest.mark.parametrize("name", NEW_SYMBOLS) From ea1566bc1872fe812364d36332706edc959b6e3a Mon Sep 17 00:00:00 2001 From: Artur Shiriev Date: Sun, 12 Jul 2026 22:53:58 +0300 Subject: [PATCH 05/10] feat(brand): add the modern-di-flask mark (Flask's horn, recoloured) Recolours the horn (rhyton) from Pallets' flask-icon.svg gold, per their Flask Artwork License permitting a modified version of the logo to refer to the Flask project. Co-Authored-By: Claude Opus 4.8 (1M context) --- brand/build/projects.py | 1 + brand/build/symbols.py | 31 ++++++++++++++++++ .../projects/modern-di-flask/lockup-dark.svg | 1 + .../projects/modern-di-flask/lockup-light.svg | 1 + brand/projects/modern-di-flask/lockup.png | Bin 0 -> 1797 bytes brand/projects/modern-di-flask/mark-1024.png | Bin 0 -> 7188 bytes brand/projects/modern-di-flask/mark-512.png | Bin 0 -> 3278 bytes brand/projects/modern-di-flask/mark.svg | 1 + tests/test_projects.py | 1 + tests/test_symbols.py | 2 +- 10 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 brand/projects/modern-di-flask/lockup-dark.svg create mode 100644 brand/projects/modern-di-flask/lockup-light.svg create mode 100644 brand/projects/modern-di-flask/lockup.png create mode 100644 brand/projects/modern-di-flask/mark-1024.png create mode 100644 brand/projects/modern-di-flask/mark-512.png create mode 100644 brand/projects/modern-di-flask/mark.svg diff --git a/brand/build/projects.py b/brand/build/projects.py index eb4316d..dde904a 100644 --- a/brand/build/projects.py +++ b/brand/build/projects.py @@ -24,6 +24,7 @@ "modern-di-celery": lambda: sym.celery_stalk(_CX, _CY, R), "modern-di-fastapi": lambda: sym.bolt_disc(_CX, _CY, R), "modern-di-faststream": lambda: sym.faststream(_CX, _CY, R), + "modern-di-flask": lambda: sym.flask_horn(_CX, _CY, R), "modern-di-litestar": lambda: sym.star_disc(_CX, _CY, R), "modern-di-pytest": lambda: sym.bars(_CX, _CY, R), "modern-di-starlette": lambda: sym.sparkle_cluster(_CX, _CY, R), diff --git a/brand/build/symbols.py b/brand/build/symbols.py index 5a7bf1b..0653f54 100644 --- a/brand/build/symbols.py +++ b/brand/build/symbols.py @@ -158,6 +158,26 @@ def async_loop(cx: float, cy: float, r: float) -> str: "h370.45c51.9,0,84.33-56.18,58.38-101.12Z" ) +# Flask's own horn, from Pallets' docs/_static/flask-icon.svg (500x500 space). +# Their Flask Artwork License permits the logo "or a modified version" to be used +# by anyone to refer to the Flask project, so this recolour is sanctioned. +FLASK_PATHS = ( + "M224.446,59.975c-0.056,-4.151 -0.483,-5.543 -2.7,-6.823c-2.104,-1.393 -5.288,-1.421 " + "-8.329,-0.085l-204.674,87.64c-3.042,1.336 -5.913,4.008 -7.448,6.908c-1.535,2.899 " + "-1.705,5.97 -0.511,8.158l17.084,31.384l0.228,0.369c1.847,2.928 6.026,3.696 10.29,1.82" + "l1.251,-0.54c5.344,22.4 14.1,50.429 25.783,70.413l178.294,-79.794c-2.559,-23.14 " + "-9.552,-89.602 -9.268,-119.479l0,0.029Z", + "M238.603,205.776l-171.698,76.838c10.091,19.132 22.542,39.428 37.722,58.986c50.429," + "-25.698 100.887,-51.396 151.316,-77.094c-3.269,-8.471 -6.452,-17.653 -17.34,-58.73Z", + "M497.601,388.846l-12.139,-18.535c-1.819,-2.018 -4.633,-2.786 -7.106,-1.791l-15.578," + "5.999c-1.848,-2.047 -4.52,-2.815 -7.135,-1.791c-5.089,1.99 -10.206,4.008 -15.294,5.998" + "c-1.649,0.625 -2.104,1.847 -1.791,3.439l0.995,4.861c-28.711,3.099 -77.236,1.564 " + "-120.701,-32.577c-19.216,-15.066 -37.239,-36.386 -52.277,-66.206l-144.75,73.768" + "c26.466,29.08 59.697,54.864 100.973,70.385c57.422,21.633 130.593,23.679 222.838,-13.475" + "l0.512,2.616c0.455,2.928 3.98,6.026 8.755,4.15l15.323,-5.97c5.258,-1.99 5.287,-6.026 " + "4.519,-8.641l19.729,-7.704c2.217,-0.853 9.096,-6.169 3.183,-14.526l-0.056,-0Z", +) + def bolt_disc(cx: float, cy: float, r: float) -> str: """FastAPI cue: lightning bolt knocked out of a gold disc.""" @@ -470,3 +490,14 @@ def task_q(cx: float, cy: float, r: float) -> str: f'r="{0.12 * r:.1f}" fill="{CREAM}"/>' ) return ring + tail + eye + + +def flask_horn(cx: float, cy: float, r: float) -> str: + """Flask cue: Flask's own drinking horn (a rhyton — not a lab flask), + recoloured gold. The bands are negative space in the source artwork.""" + sc = (2.04 * r) / 500.0 + body = "".join(f'' for d in FLASK_PATHS) + return ( + f'{body}' + ) diff --git a/brand/projects/modern-di-flask/lockup-dark.svg b/brand/projects/modern-di-flask/lockup-dark.svg new file mode 100644 index 0000000..946c5cb --- /dev/null +++ b/brand/projects/modern-di-flask/lockup-dark.svg @@ -0,0 +1 @@ + diff --git a/brand/projects/modern-di-flask/lockup-light.svg b/brand/projects/modern-di-flask/lockup-light.svg new file mode 100644 index 0000000..3805246 --- /dev/null +++ b/brand/projects/modern-di-flask/lockup-light.svg @@ -0,0 +1 @@ + diff --git a/brand/projects/modern-di-flask/lockup.png b/brand/projects/modern-di-flask/lockup.png new file mode 100644 index 0000000000000000000000000000000000000000..35824333f6d274b04244ad1e010b31a37855f9d4 GIT binary patch literal 1797 zcmYjSc|4Sf8-F8=E7weEt3l-o8CN>cxJ_dm!)&%8Gm?qO)QZ74n>P)%2_NKGQ`%_J zV4Emm>})KV9E*l^zRt!iM=HmU-9LW&e7?{3`99~r57W)XQC{Xd82|v}F-~@P0N6v` z(f%;;9VX@79Ni6W&Yt!=(Tsv`PX33PfY~*?=`~kViu+E{bXU8#FadL_XUjdHC3zP+ zlg&)PBp^WF%L|B)N0UgrcmN%bCJ+cM8NhZtu)V!=^8XeaD=^r})Wh&D9>C^SQbL5iEuehw(p52Y$4N*P-NSb2otUYOe&kczD3Q>vxDOfP>wy*s8 zVEuOVjd^kXy%N<`CUM~@Mhz60$?sJqC{!$^8KM_-@n4?O%8QH&y$o#(tOp&J6C45yCkUp*poi6=DuhB%h5l zQBeh_VB2Q|H6P_sGTE}`MEMWz_c}m$sL15<1b^SU8OZYHdw{DeBYx&8v`F%8Zfm|J z{mdhQt&=1|FS04x9j6Ab>iWY10%~hfM4yL5*~?nBah|=d3RVGPyhLi;1-EEYV)FDs ze#;69OEZt|*mfja`gbAQr>B0Dn9_z(y6&)8YTEjO)CVCH^2Jga^U&(TXX8#*xeMp9 z&*F5)yHJt$snH&zeP+8*yO`=a~w!8S&@l7xtI8M%D&dm21)&ipXh*+U(T_dk8_!LVP8yrs z`UWjPW;~DrmdQY1!s`7?b*&?v8A@wER~WiveZrFq=yzh+tJZ~!s*4XR^0ca=Mn3e9 zGG97-=~6inE(l}cAv+oq^Ah|TB

pCH3fO=@Xw3u(%*T-78fP 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 literal 0 HcmV?d00001 diff --git a/brand/projects/modern-di-flask/mark-512.png b/brand/projects/modern-di-flask/mark-512.png new file mode 100644 index 0000000000000000000000000000000000000000..fd191dcbbc82d9efc101b8dfd7247e62e0b66f59 GIT binary patch literal 3278 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 literal 0 HcmV?d00001 diff --git a/brand/projects/modern-di-flask/mark.svg b/brand/projects/modern-di-flask/mark.svg new file mode 100644 index 0000000..48dbd54 --- /dev/null +++ b/brand/projects/modern-di-flask/mark.svg @@ -0,0 +1 @@ + diff --git a/tests/test_projects.py b/tests/test_projects.py index cf2c6e1..67a0185 100644 --- a/tests/test_projects.py +++ b/tests/test_projects.py @@ -40,6 +40,7 @@ def test_project_frame_parses_and_uses_tokens() -> None: "compose2pod", "modern-di-celery", "modern-di-taskiq", + "modern-di-flask", } diff --git a/tests/test_symbols.py b/tests/test_symbols.py index e0d0113..40fe379 100644 --- a/tests/test_symbols.py +++ b/tests/test_symbols.py @@ -51,7 +51,7 @@ def test_util_symbol_parses(name: str) -> None: minidom.parseString(_wrap(getattr(sym, name)(50, 50, 23))) -NEW_SYMBOLS = ["plane", "hopper", "pod", "celery_stalk", "task_q"] +NEW_SYMBOLS = ["plane", "hopper", "pod", "celery_stalk", "task_q", "flask_horn"] @pytest.mark.parametrize("name", NEW_SYMBOLS) From 699f9e25f58fbc63378eadfa761d093f09c9eada Mon Sep 17 00:00:00 2001 From: Artur Shiriev Date: Sun, 12 Jul 2026 23:00:39 +0300 Subject: [PATCH 06/10] feat(brand): add the modern-di-grpc mark (bidirectional call arrow) Co-Authored-By: Claude Opus 4.8 (1M context) --- brand/build/projects.py | 1 + brand/build/symbols.py | 23 ++++++++++++++++++ brand/projects/modern-di-grpc/lockup-dark.svg | 1 + .../projects/modern-di-grpc/lockup-light.svg | 1 + brand/projects/modern-di-grpc/lockup.png | Bin 0 -> 1708 bytes brand/projects/modern-di-grpc/mark-1024.png | Bin 0 -> 6174 bytes brand/projects/modern-di-grpc/mark-512.png | Bin 0 -> 2627 bytes brand/projects/modern-di-grpc/mark.svg | 1 + tests/test_projects.py | 1 + tests/test_symbols.py | 10 +++++++- 10 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 brand/projects/modern-di-grpc/lockup-dark.svg create mode 100644 brand/projects/modern-di-grpc/lockup-light.svg create mode 100644 brand/projects/modern-di-grpc/lockup.png create mode 100644 brand/projects/modern-di-grpc/mark-1024.png create mode 100644 brand/projects/modern-di-grpc/mark-512.png create mode 100644 brand/projects/modern-di-grpc/mark.svg diff --git a/brand/build/projects.py b/brand/build/projects.py index dde904a..752b969 100644 --- a/brand/build/projects.py +++ b/brand/build/projects.py @@ -25,6 +25,7 @@ "modern-di-fastapi": lambda: sym.bolt_disc(_CX, _CY, R), "modern-di-faststream": lambda: sym.faststream(_CX, _CY, R), "modern-di-flask": lambda: sym.flask_horn(_CX, _CY, R), + "modern-di-grpc": lambda: sym.rpc_arrow(_CX, _CY, R), "modern-di-litestar": lambda: sym.star_disc(_CX, _CY, R), "modern-di-pytest": lambda: sym.bars(_CX, _CY, R), "modern-di-starlette": lambda: sym.sparkle_cluster(_CX, _CY, R), diff --git a/brand/build/symbols.py b/brand/build/symbols.py index 0653f54..fffed4d 100644 --- a/brand/build/symbols.py +++ b/brand/build/symbols.py @@ -501,3 +501,26 @@ def flask_horn(cx: float, cy: float, r: float) -> str: f'{body}' ) + + +def rpc_arrow(cx: float, cy: float, r: float) -> str: + """gRPC cue: a bidirectional call. gRPC's real mark (two diamonds pierced by + an arrow) needs two inks that contrast with each other *and* with the page; + our two-colour palette cannot supply that, so the mark keeps the arrow alone, + with the heads symmetrized (gRPC's own are unequal, sized to their diamonds).""" + w = r * 0.17 + half, reach, rise = 0.98 * r, 0.34 * r, 0.46 * r + out = ( + f'' + ) + for sgn in (-1, 1): + tx = cx + sgn * half + out += ( + f'' + ) + return out diff --git a/brand/projects/modern-di-grpc/lockup-dark.svg b/brand/projects/modern-di-grpc/lockup-dark.svg new file mode 100644 index 0000000..f853f1b --- /dev/null +++ b/brand/projects/modern-di-grpc/lockup-dark.svg @@ -0,0 +1 @@ + diff --git a/brand/projects/modern-di-grpc/lockup-light.svg b/brand/projects/modern-di-grpc/lockup-light.svg new file mode 100644 index 0000000..65b5c4c --- /dev/null +++ b/brand/projects/modern-di-grpc/lockup-light.svg @@ -0,0 +1 @@ + diff --git a/brand/projects/modern-di-grpc/lockup.png b/brand/projects/modern-di-grpc/lockup.png new file mode 100644 index 0000000000000000000000000000000000000000..8d6f3b15c956016f0a68785764c2e2623f9c8611 GIT binary patch literal 1708 zcmYLKdpy&7AK%i1I4M1thzi+B!iL_WI+$U`w@|M3{b!@`-3U`skW-uK zxK})aFkU_M?xDTp*}4{jgC%(Q@Z<2JtL$Yys70)Ogd}Z+BRI#$He_J+>Ks0(nH0G5 zHV6AOsLIgfRfA>ce#!J=*0;y9htpVINR=@AaK-XA+N^c#ou-u+ZBCy5nCNsNO^OE7 z-6Uzu*x}Nn84lirTUjeoz`jy0pQ=|FU64)Mzq1)W`Gpv=P8k9#Y!t8UBzcD?tl}C% zlOO5qyX(C+W|P-G9DZ-|TQhM1LxD;rMVpq7z&iW=g}X;r+$Bc4fHOPfahpq8l~# zM~KY`RV@L3>NgZQ-MRio)bz!%XiS)q+}!>*DGg*Y7Ztwv^~5)2Qrzmwj>Z04mvUXj zZ|7-r-6_PwitfPXv>U$-Uap=m=COMLS06aHC$mj@GB%EHCyZx05VnT-tfgHG7P95C zI&cK(_^JpGE1Of@{=oE>?(7}ZjB1YE1gXyr?}+yOd}j7(s5SB24ivF81vG_eY;JU1t6O1=$;~nZ#|Yj5tn`(pOTJdK_?#(-D{4( z+6()M0#m6}$S|{y-Qvyk2wdlHV*cF(fj2KO*o_c8nE*q5-GmzIm8qX{PLIYWqFutC zkHoWTC5CZb-4y4fdyeeFS)A%2Z6FvcTRcn0JZ9jBhK6c1DSsfNvMzmyVTZC&rg?K} z#DaV|Y?(NU+@C=Br5mV3ZaA-{Y!c7CM!B1LnY$DBCMl#ON^RhamB7L+ zO3)lNS_6JHCCZMBXR!9r4c2nQ7Xdv@Qm3U3TFMRA?fA-f%d!eQXi#T3ozrHf^B2_7c^?@n=BF;x@o|X;^%KDFsbdfs( zXa>7FRzjg2>TA2lP?F!HfqcGkL+HZ%i+VC)t+y4-4)`@xM(r&@#94W?QnViJl`tAg z?XgZS2iVWAPTBC$EC#tOIarockCZe?m+oT6+@2+vCC&n^7vCpMga4)!CeO$9pLy-w zvD`D*i%$?ah6H^5j0BKfQzQMDeG-oL_tgA5QQz?_#KXU`+2o`M*RF2l;kfr literal 0 HcmV?d00001 diff --git a/brand/projects/modern-di-grpc/mark-1024.png b/brand/projects/modern-di-grpc/mark-1024.png new file mode 100644 index 0000000000000000000000000000000000000000..3397b710fc74b6eff5b382ddfe41f04680539bbd GIT binary patch literal 6174 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 D37_4& literal 0 HcmV?d00001 diff --git a/brand/projects/modern-di-grpc/mark-512.png b/brand/projects/modern-di-grpc/mark-512.png new file mode 100644 index 0000000000000000000000000000000000000000..50e2b5ba00493f6890cbb2703fa79a67708b5bfa GIT binary patch literal 2627 zcmdUxYfw{37RS%MfrMw`AS)3tAny1W#4s*oP#y+Qk>_RrK}F%Nh=2qq!bk$5+`$nf zpt!EaMQpG>(s(zK*dD0O-4K+2{*^swE0qBsCiI{@9`h#_{ssq~?7g*hcuar@+@-|NCiR z8|l{~1htqSgQh+Nd<4$rNhU(N2gx=0QIV(iC0lvRt{tTUsbafu}nA-tl@OOvj3_om3cYb zX~r@KS{_pIw+{0M_J0jpu(2j_w7YpghnOraa&QtH*fTnMn>I1C9D_8ox(;J}K101BRgAaO2cySywjgaR6XuwlV(3754D zy&M^2_%!KNdTDpg?=$QHIub$DHXX(NVYN$I^q5Ksj*e0JI%{AW@~dYQC`5;msTk9vQ;IOALV9#w@44DbX7g&`*Kr zCPKJb2CjhhW^iWb;&C&!ZWO_Hh&@OXO?YEQ?d1NLx1EkSivq*r!3h*etFde#g_%uS zX>*3*p-LZ)8!f9tO#8NzlwGzNYL_5VU6-{e3ZiMysz*v7^OTC2PAWdBdm#u?bQv0* z5)idmi$dWY4LrDe$BfwN>itgjTj9AuQK@l(DTg$9`{H$~UVa}?1|vRXC>rdD(-Gw$ zM6XHHtcK*}a`B5b@+P^4qzka&Xscc5dHeI|nuA`BXas*@&yt7xmY{;MXb_M6<)9Y! z?8h)fS~-3}-p;^HOgU|fkv{%o~>NcCcu6%_Y;)CeGVs zrcH{r(1aha_uRd*+i`V*OdOG!{;5j9%#bx`m1TTrr87?$*Vwd14b`w7rZ20t>nsYT zl%1TKh+t+;&kD*i>rL>@smQVYm;u;SI~PAT+>GMO15?hqfC-7DTDEr5XM0bP%mi@m_RMDN^VW0JHW`|mGuO|n8kv3utf%cfkLYYJN1 z7Oy$fVXPtQ>G$xf2ylliI{D0{N*`3x)XICks%RzXJFLI@dBp>iGuO(SiS?)Bt=}A9 z(#G7Gir6L9#6B^?4*>S=eO0m_@qxNNP*Z%zkeK8s>leury5Xt9$kP`tpGNy-X@ z$VJ5U3N9SVM*f?o|JR?z(Q}&-YeBRrxau-b_P17EOljh~@jp+$y2y3yNQ`NdLc diff --git a/tests/test_projects.py b/tests/test_projects.py index 67a0185..ed0f1c5 100644 --- a/tests/test_projects.py +++ b/tests/test_projects.py @@ -41,6 +41,7 @@ def test_project_frame_parses_and_uses_tokens() -> None: "modern-di-celery", "modern-di-taskiq", "modern-di-flask", + "modern-di-grpc", } diff --git a/tests/test_symbols.py b/tests/test_symbols.py index 40fe379..2f3dd2d 100644 --- a/tests/test_symbols.py +++ b/tests/test_symbols.py @@ -51,7 +51,15 @@ def test_util_symbol_parses(name: str) -> None: minidom.parseString(_wrap(getattr(sym, name)(50, 50, 23))) -NEW_SYMBOLS = ["plane", "hopper", "pod", "celery_stalk", "task_q", "flask_horn"] +NEW_SYMBOLS = [ + "plane", + "hopper", + "pod", + "celery_stalk", + "task_q", + "flask_horn", + "rpc_arrow", +] @pytest.mark.parametrize("name", NEW_SYMBOLS) From b75020b9350ac6be78541c8f0f02e29ded0f8ac6 Mon Sep 17 00:00:00 2001 From: Artur Shiriev Date: Sun, 12 Jul 2026 23:07:23 +0300 Subject: [PATCH 07/10] docs(architecture): record the second partner-path mark and the gRPC departure Co-Authored-By: Claude Opus 4.8 (1M context) --- architecture/brand-marks.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/architecture/brand-marks.md b/architecture/brand-marks.md index 42908d7..0acd72e 100644 --- a/architecture/brand-marks.md +++ b/architecture/brand-marks.md @@ -21,9 +21,17 @@ One large-format logo per repo: the constant green+gold snake-frame (`geometry.py::project_frame`, margin 9 / arm 53 / stroke 11) with a single 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`, +project templates reuse the org chevron. Two marks are built from a partner's +literal logo path, recoloured: `modern-di-faststream` (FastStream's) and +`modern-di-flask` (Flask's horn — the Flask Artwork License permits the logo +"or a modified version" to be used to refer to the project). Other +integration cues are redrawn evocations, and three had nothing to redraw +from: `arq` publishes no logo at all, while `aiogram`'s logo is a lettered +disc and `taskiq`'s a wordmark, so those marks are inventions (a Telegram +plane, a hopper, and taskiq's Q-creature). `modern-di-grpc` deliberately +departs from gRPC's mark: theirs needs the arrow and the diamonds to be +different inks, which the gold/cream palette cannot supply, so only the +arrow survives. 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`) From 05184b919387385f6bc63376790dcf2129f683f0 Mon Sep 17 00:00:00 2001 From: Artur Shiriev Date: Sun, 12 Jul 2026 23:44:04 +0300 Subject: [PATCH 08/10] fix(brand): stop cream ink spilling onto transparent background in three marks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit task_q, celery_stalk, and plane painted cream where no gold shape lay beneath it, violating the mark contract that cream is only ever a knockout of gold. Invisible on light (cream-on-cream), but lockup-dark.svg renders on dark surfaces where that ink turns into stray bright-white artifacts (a floating dot in the Q, spikes off the celery bands, a nub off the plane's nose). - task_q: drop the eye entirely — it sat inside the ring's hollow counter, on background, so removing it doesn't change the light rendering. - celery_stalk: inset the cream bands' left edge to the capsule's curved cap boundary (only where they poked past it); the always-safe centre band is untouched. - plane: inset the crease's endpoints off the hull vertices and switch to a butt linecap so its stroke can't spill past the nose's sharp point. Add test_new_marks_have_no_cream_on_transparent, parametrized over the seven marks new to this branch, rasterizing each mark with and without its CREAM knockouts to catch any cream pixel left without gold beneath it. db-retry and faststream-outbox carry a similar pre-existing hairline from _cyl and are explicitly excluded as a documented follow-up. Co-Authored-By: Claude Opus 4.8 (1M context) --- brand/build/symbols.py | 44 ++++++---- .../modern-di-aiogram/lockup-dark.svg | 2 +- .../modern-di-aiogram/lockup-light.svg | 2 +- brand/projects/modern-di-aiogram/lockup.png | Bin 2061 -> 2054 bytes .../projects/modern-di-aiogram/mark-1024.png | Bin 7365 -> 7341 bytes brand/projects/modern-di-aiogram/mark-512.png | Bin 3253 -> 3264 bytes brand/projects/modern-di-aiogram/mark.svg | 2 +- .../projects/modern-di-celery/lockup-dark.svg | 2 +- .../modern-di-celery/lockup-light.svg | 2 +- brand/projects/modern-di-celery/lockup.png | Bin 1751 -> 1756 bytes brand/projects/modern-di-celery/mark-1024.png | Bin 5941 -> 6057 bytes brand/projects/modern-di-celery/mark-512.png | Bin 2360 -> 2370 bytes brand/projects/modern-di-celery/mark.svg | 2 +- .../projects/modern-di-taskiq/lockup-dark.svg | 2 +- .../modern-di-taskiq/lockup-light.svg | 2 +- brand/projects/modern-di-taskiq/lockup.png | Bin 1947 -> 1904 bytes brand/projects/modern-di-taskiq/mark-1024.png | Bin 8289 -> 7731 bytes brand/projects/modern-di-taskiq/mark-512.png | Bin 3590 -> 3354 bytes brand/projects/modern-di-taskiq/mark.svg | 2 +- .../2026-07-12.01-seven-new-project-marks.md | 13 ++- tests/test_projects.py | 75 ++++++++++++++++++ 21 files changed, 126 insertions(+), 24 deletions(-) diff --git a/brand/build/symbols.py b/brand/build/symbols.py index fffed4d..87484f2 100644 --- a/brand/build/symbols.py +++ b/brand/build/symbols.py @@ -415,10 +415,20 @@ def plane(cx: float, cy: float, r: float) -> str: disc with no pictorial element, so the honest cue is Telegram itself.""" hull = ((-0.95, 0.02), (0.95, -0.78), (0.30, 0.86), (0.02, 0.28)) body = " ".join(f"{cx + dx * r:.1f},{cy + dy * r:.1f}" for dx, dy in hull) + # Crease runs fold-point -> nose (hull[3] -> hull[1]), a chord that meets + # the hull exactly at those two vertices. Inset both ends off the + # vertices (and use a butt cap, not round) so the stroke's own width + # can't spill past the polygon at the nose's sharp point. + fold, nose = hull[3], hull[1] + ex, ey = nose[0] - fold[0], nose[1] - fold[1] + elen = math.hypot(ex, ey) + ux, uy = ex / elen, ey / elen + inset = 0.20 * r + x0, y0 = cx + fold[0] * r + ux * inset, cy + fold[1] * r + uy * inset + x1, y1 = cx + nose[0] * r - ux * inset, cy + nose[1] * r - uy * inset crease = ( - f'' + f'' ) return f'{crease}' @@ -448,16 +458,26 @@ def pod(cx: float, cy: float, r: float) -> str: def celery_stalk(cx: float, cy: float, r: float) -> str: - """Celery cue: their icon redrawn — a banded capsule with the pale open C - at its right end. Measured off celery_512.png; Celery ships no SVG (see - celery/celery#5981), and the C is *open* (facing right), not a closed ring.""" + """Celery cue: their icon redrawn — a banded capsule with an open C, + stroked the same gold as the body, at its right end. Measured off + celery_512.png; Celery ships no SVG (see celery/celery#5981), and the C + is *open* (facing right), not a closed ring.""" s = (2.35 * r) / 512.0 body = ( '' ) + band_w = 9.0 + # The capsule's left cap is a semicircle (centre 103,256 r=102), so its + # boundary curves inward away from y=256. A plain x1="8" pokes past that + # curve for the off-centre bands. Inset each band's start to the cap's + # boundary at the band's *farthest* edge (accounting for the stroke's own + # width), plus a small safety margin, so the whole stroke — not just its + # centreline — stays inside the gold. max() keeps the already-safe centre + # band (whose boundary is well left of 8) visually unchanged. bands = "".join( - f'' + f'' for y in (205, 256, 307) ) arc = ( @@ -471,8 +491,8 @@ def celery_stalk(cx: float, cy: float, r: float) -> str: def task_q(cx: float, cy: float, r: float) -> str: - """taskiq cue: the Q-creature from their wordmark — a thick ring with an - eye and a descender crossing it. taskiq publishes no icon-only mark.""" + """taskiq cue: the Q-creature from their wordmark — a thick ring with a + descender crossing it. taskiq publishes no icon-only mark.""" ang = math.radians(48) dx, dy = math.cos(ang), math.sin(ang) ring_y = cy - 0.06 * r @@ -485,11 +505,7 @@ def task_q(cx: float, cy: float, r: float) -> str: f'x2="{cx + 1.02 * r * dx:.1f}" y2="{ring_y + 1.02 * r * dy:.1f}" ' f'stroke="{GOLD}" stroke-width="{r * 0.30:.1f}" stroke-linecap="butt"/>' ) - eye = ( - f'' - ) - return ring + tail + eye + return ring + tail def flask_horn(cx: float, cy: float, r: float) -> str: diff --git a/brand/projects/modern-di-aiogram/lockup-dark.svg b/brand/projects/modern-di-aiogram/lockup-dark.svg index bfd20e1..9d62a05 100644 --- a/brand/projects/modern-di-aiogram/lockup-dark.svg +++ b/brand/projects/modern-di-aiogram/lockup-dark.svg @@ -1 +1 @@ - + diff --git a/brand/projects/modern-di-aiogram/lockup-light.svg b/brand/projects/modern-di-aiogram/lockup-light.svg index a602b17..f934ea3 100644 --- a/brand/projects/modern-di-aiogram/lockup-light.svg +++ b/brand/projects/modern-di-aiogram/lockup-light.svg @@ -1 +1 @@ - + diff --git a/brand/projects/modern-di-aiogram/lockup.png b/brand/projects/modern-di-aiogram/lockup.png index f9f61aa35ad03efd7c932a853e29eebc97a0629f..3454ba3e3ebb84e1bf11fdaf2df867d1902f88a2 100644 GIT binary patch delta 2006 zcmV;{2PycC5QY$tDIPLwThE##@afk8fPmYzV(5tgRaI5u#)z?;0RR60kz65v%7_5; z@#o2j0Lh8~$%+8TiU7!o06<`1ELT@RfI#WkuzLx#EC2uiAaqhrQwje60{#U9{{#U5 z{r-r7%@s~(oQa~ZU_ei|8IlQsQ>^6HAzH4RCwC$o!4UWIt+l*pRN;PJX1Ej z|63k!%NY=8QbH@;Kx0R?^?AsDibIPMWtLK)34RwCz68S2j+21l1;IQ9%;!ei|9pPg_i-5?jIJ#kMG>3ze)?Nrwku=$ z^VipF-N$8oFbct3mbcB$TK?nf>%8mb@(f@kzpU`c<@11f+k4x;YA#hX?vl7v>)C^m z%PSh`BMxZY2gc1|p3A>~m-X8-gAuyjmxe^~kl^keV8R?`9{}dSSWzCh@bkOm`9#iiip&6iFq7py1GA7O7tnYr zrBlclb2_>hN_RbiDOfWXs_Nuo9I~#Ze<+wx zE|KB2sZ&f_=C+aXiU?qsYSdca<(hi5V1g3W3bh5*Jz!Mx#h(ZU6d5{Es;W$291T_; zXi_D88i@)*3cCvo+_Y3}N4az99}32FA887wnvFCUL`+hDTwkG~+RSI>%C?$$`%zw$ zOauc8%UIgZN$p5-N_n$bg|3o!NAUT+}B=4W11dHeIDOMMd)KD_aTm^qf1gC zisCknA|En;KsR0XPGyTYbR+~r;!f1eLc(_#kp@#7F^jnT_??i>|L(yAl`$SfZwIsO z!4ftwy@nq+m4!~{tClE)DZHSzArkD(i3dZ|96+40MY^w~A3R z9qFu3lEoMpF{ICx41Ev8=k#r-JEpRF)49N$BbSbUN0-AF|4>I2t!bRArR!Z~Y9%ze zHxC0N!J9&WS&POOc4_wNE}YUyKbV6w9$^DaW^os$0lg!RO%5t+ok@9wDqPwzmf7e1 z4_W;8yY_(j@LzZ3cfq9Xgt9i2uoi`FErC%+XAINjs24wp2#~7*hP#X$;w&4BzssVM zS4J9tU?6yJVu+M=fH^v^j0)8NlkOzv~IMg zGSR3$1^icTyiL(SIN>gu?U+^lKQW3o17tFjP4?Bq`JW@lm7>Q z!9ZWzQ{c(V;V(ZZ&&UNjEqI9uu)V#ROi$+z`TcCa``i0(vYdA0OL$Tl>!yARiw(8HFyF%UP>XE zt6-dsobH}|47a~^Bvi{Q>nPIuT|r%cbMd$FA3@Z;UK!2Z&f!C5RZap11PetLS~C@7 zDl-#^bPfWObc?>|aww{~kBI{o#)P9fQg-ZPLYEihXTa2#m;OOuBq2U%LP&_)6OvN3 z_o@W=fqN#*6@D_mtIpsh5^Tgt{Hj&OUQ0-;WaAdgRB+0iX9!i)ii`O8-+0x3iZ9x^ zPa)I?s-YhWm_!yTozh4sGd1VpR5tL`!RpG%q$!_Z&Pnt`utjqpGszRop{GIIklFuv zFbbHg5hEKF%yGu*|-vJ|%yL6#JYXtMNVD1nEgJ2L0fQxFqnreS{+1oKKg*P9#hs$^ZZdJV``BRCwC$o#|rYI1GT3v;~IF>~4th zN#On8a(!FQMW9K6sr08Uc4S+hWy?xJiyGxAr9cz>U10bD2uC}ve*%V++vSi6+Hn;y z9V_1GS3Ny)R@G4Z7?VZ2Eia01cQQL z5DW@}K`2&%WU>*bJ&qdq+?R5HgjLY(1bZ^-r zir7=1r@sWIJQ~w$E^qA^m*v4I1apPTWzz&Mn^7*W07mj@g$0+d1E$=2+yByBKDv3A z#HBeuJs5eoqLDu00j>MMxHZgkdH*<O(HO;1eZ7?q%m6exslgXRq z(p(VCBf+%Crs;8cGe7?zn8$%BH_aHA0n^U_Q!!T56&HSempos{nJ$qT0A{LG8JL|k zwSdNLEuBKff0)xT#8A4=Bbb79YcUQl)yj6+#j@^oHMD89F*6(%>nByVY&$yWo58gE za}SF>z}R2fyTIrmmGjW1q~;eDO(B)jRTe4B+xE2De6vFmDFmKe?dhE|8h#`qA3n#e=>B-4Vuck!Ia0Q8RTLDvZ1Yi zE|}0Rk>RzeZ7e(Fwvq7@5x_9j>9xMf4Yjaff)dqBwFT89U{v?Tp9lst875Kcs!U)U z4OUk)sgk~oLucuMw$;qEK*#5LPNKiugsMlHS_kP zyr`K7e+Cqmv9yzuT2FFHdAC{R3g`$Jt{p;FTide&g4t5ng7r%kTp)CnCNSDTBoX#X zU05*VRk6&BLxe$dI<`tpgBe`IaxP7IKbT-(XFKkDFQYNd45hw~pQ0knF;lyW-c-0E z1+pma&?s`30lMj7bSc|K*O3qmi6>FB3JE`9e?)So=rOyv{rHoRu3vdDL1oMb(c8h4 zBUr)#X4LRAm$ESFeAg0%u!I-X4n%^pIq_g#OAOOR_ zvLl`KNwOFN9z(`L$uRdoeokMuy<;hBFM}J*TjVn6FmpHm&_@-mY4-Gkn_YDpB{aD= ze-8tm;7uXGszu`qyEJ=s7cS{!984umMA!k7S=^;*!0d>=$w6mrFewYDLWKMqosRzJ zZ2tSrNT58j_1^|29Ve8vp@h9C>}UzhGCE_JDM!8dMMQvF9WdNgd|hqihvoqi!AT z6*edw1vATIh>6d1;3&zOU;>eI| zndo$%g6&ZDz<~P+YGp7+{sCM@9Og@4QbgstCO|ObBTnY-Ud3;~<#WMgy45h4^cTs& zz{s|6_~4xy(gOp0pMC?F&woCy-k$st7_*jCHH<1*Iwlt3&`Hw#74DET2aIrufp{Jr z1anC79|QwqZBK!xD32e8JVs^Xe^?g`H2Y-@Fvj*a6~kgOz>He3IwaM?slw*LY!*$< z1QT@^;xGaxnBVT)85kLxRNwu|3EqVAJFm1GYy9O9%5~>vFknJK>#;hR{ z;PIoBlDP`T*~sZ0ImdAOT}MLoqOyS|ecTn)bvJ*T{}Dvp8PS6sjtNsgZJo@CElwm{0iDe6Ko#ACX`qPU5dxRh+ei^jbDyu}lr8%6Wy*MXk7qxBpF4 zt@y5AdmB=Hpd0$8fGK35f77Xqgf`P~CYQ3APaPbuJejoS9n5DEeG_cgJ;$ta2XpSz zAkJm>KOT$%ChO$L76mi^DV@#K*8g+Bh!idr^cMTw2IdC6<+RCv3Yc_1rc%qUWDv|v zyf+hD|IYz4aI~UVexPSre=s-WE?Wcx9(dc< z>pbwc@Ke)23QWD?lbB0C&5mFe0V5WF%K*VV>Hon*FbD?0AQ%LLf?yB~3W7l}2nN9* z7zBf0P`&`>0^f_dAeg5ClfSWaoGE7n^Sxm15Cnr@5DbDrFbD?0AQ%(`gJ2L0feUt@)H+ZZlGgg9+6q@|u|*-(w&DmX0y5>GuhME; zY^y@OGFbIus}_(dB14Y0)(HVeK*7X;L8gFVN=VLs_kX~k9!y*cE||6*hi9-Oa^D74YWUbIQN@Q}v1W9()E5 zFYh|}H9Tp#H!XCbXXrvgK+DFy6uLyoD3vM|Fbtl!v;(GxE;O_^T=*1buKLSGeu$IU zx%>%Tn!a*j|Il;A+xmv#x2YeW$gyHS)%iQ``Tt{5g?nzuWRLS3Z4f1Bt4hv#8c_ zvhP~aPM$G*d>BD{_UTD^7yz-v9X#r^Yg=e<2oI! zncLTs`U-m_QBhX_Ld6#H*YjCqezv0bft50at0b>IBr@TCA!P21?Bl*I?idS<`|ZL? zy}aglm=GeqGiqYh9c}SWkXfN7X#(80nIt$?TY*yAc(rfOqjv!u3ZS=nRc6>AxOu`E zd`mxffzbQDKdj`&;&z=CGalf_h^RF}_8?m=i0*kcrea?`v80VlcVafj|8zJzX5|h+ zX3Z438Gl^B2IiG&MM5Rmqk{#%)1VLN4N&6$zjXWn7+iQZjSc*5BnTNE({DGZ-GxFB z{;H$Ii3ter*);zx6O<*?g#Z7g^S@)lzxlR<6{X#w%4yMaP}hCdA<#`~#x)_Y;tDA&sZr;(_Vu~2cYxZB*N-cV3ctBIQlnTHEc3UJfL zzRI+@*fKu44`W-U0Fxt!g!f$Q5x_i0)@-Gen%#8gVwpZ-@WDG+Ss1Gp*&vBzba<}Q zt36*3sIav;tzqTDsC<1~ogj11$naQVTAv%N)pR5)V1ht7{I`FenHzX#`U#l{@CQF= zbiTIpc;3S9o^XE@$NB>7o1zozkel$W!><$M`AZN)fv5i2-UW3*-*yb0{u+8~34 z?dUt(bT#;$HQ2!m(VW0VT&{pay8q9cuHSXuhPGW^A2o6&HA|fTN?OwWU1)PaTXtz* zNACE5NKTMhl}Azrd(K639gNAO0Y?k2;qHm)7TKHZpJQ;x={#b*4`WWCu+{Izl8(n# z0mx7$dtR&k{620y91%Z@7#fI!FN(fcttPdvzOo(V?cUNYKOr>NB8gMo&A#M|g}?eb3(PxzqQlVek^X*i3G}YJF*Chus zm8j$U-o4p!1G#Xu!MAwwN#TBqd54{a>?1Ns_%sA~VW%cTZ&B2m^A*9n-xZX-gmY(; zICVM65XOZ$Mo-1@Er~`R=G@(sA^gk<;Vh23Qki1SghVY?i9K&1h{N}ubQK#(!$X!@ zx;nVmQZ8n~`b_V$6ykJpov7_V({^iTdLUy!2HtLxThtyTL@~4m4L$N8sH7wYdOwH2 z;u71?G8AE3T-Q9wKy({)*HD0?_DR>1`mEyC4Ps9{jyK^LWmjgy5i27zZvx_#F)rWw|iN{%=+~L%%a?N zwaJ>Pt)Y9SaP_HV0YB|*^5-BYLm?Uju-}rEO8m8Ec{e6g+x-?<59sb1^>ucM0$^&A zyZ1EmUB24$SrK4;KgvBjzt zih5!Nnb~$CRR2KxWO}QZDe=Xs1>xNpokF(3QHKC3YIbUj>gWsuJY~8x_+~o{vvwMvG9H;)=jsn%zPSC~zYcxWxR{MuDoa zd7Ta|ns>%GEy=f@WZ6OAQmXkpI{a+EgxWMq)@i7COf_GOZ&cJ-u?qrusPT;?Ctsr= z%YFd#WoI6lAcdG^^!Ncg%cNqcXr*V4^j!Z( zfSiZ?xrqBw=@?4c6wk3F?qzRi*+SL+xLVeF(roT2q!;zU2=((J&|5PC-4kS)O-8vx zXE9x9DyduZr3B*n<3)L7H+npTnsdXQE1NAdC~k?FGTwB_mPQ5UrT#%xwfccIGdn+9 zh+AznbK6;POHN! zzzc7cX!7t@s(HRJd^Au&D3N}z^!cl?l;ODhQS}mVSkjDow49mDLrLg)K z6V5<2zWGt($jKIKNV%#@=UJw?aUxTWg1Uh zXN#iYX+B_QlY27ojpB~-7&+fN&DW)1dz=EEDosc^0|BeVHcSM3(U)7_TOK7)9qD)x z#b-Wx5Y~-^2QnBsDCD994kKlsh%?)&)yN+m*oZUR`N2sX_=$8&Of3q7n0XJc+ap0h z`#Jqr6raq-hFJoU4No2_ic&j-%3Q?wEmWodGET*j)Xjn=t5LrTd@twro`!&RIB;|1~q7u^AZ zS}&u00i&5id1Sa0n&?2vTwOKhT)nzY0$8)*h%Nh4i;PTk2L}w{%s)e+VOM3AxL$Jy z6^aF(Z5Pg(%fkh#$%aJSEMeO`UY|k4%nmf|rqHGN06B-ItyWu$nC0-F=@u!{h>3!k z1&7itlv6tR6O36=&h7MpDFs52axk28HwUlg))d>?z+$LMOKS0Tn?}TViyOx>t*geA zlHqnR53@tXOt`dD^PwCZFg;|hKr-?=LYjoiYe?J~u}kj(BE}0s*A`*HNGS#n2lH$d zbV}Inh;}{s$_|cFDf*$h=vk?xu3l4*Hl-=VRT)08^doK!U9`-}T<0#_xeShAlq)|! z%6{pZm@>aieJO~6$(@zV1{CN!ogW9ZT+`H6Gn@Z3c0 zprOp}WNZ29;n4-1=48BNx>F5dn-1?`PhdP@Qn42*$B9OiKtL>>bb-|^Vkr*daNq%F zv=Vo$ncb)`5h9AEMeikWNp2Vu66T9QVPN*&baI(qLSaSoJY7?=SO)K47IAT6+yjM* zAgfXja+psZYS%=Wq&;#wxic8Ua;P%QHBp)|0$=xb$J4N_cv&cy7J$di{!v$O`|2;P zVNZw{vqfi-)O_I~yQQAgU{#t1XR0I#2G90eQw$;TG#5n_4)4Y1uv^~b%ORMEZP`14 zLOXHlD$WjveuGrEToW}i>yl!fzbh8TiQ&~366GsR8d|7;A(k28!3_^t|4kN622Q}S z7ZPlIznsKc@BPWJe(M1~zoY+nChe|%Oh$g;cqOFuACP;V|$;7vPzG3IN zL{kH&1%AA}C_fQTc5lUi0_Nyz+II!PRMIEKFaAhhkYRbx)~EV6(FOb1`8pH~E+Y~* z(6LM8#GL+(!#uGZP*mwW0aZs|n}lOX(Mp1C88_@PtnBKzCR!xe%j#i#!X6{wQ`*Jp z3`K2UGm%>!&P(mK2@l01usj*OXq!8i8Bj0sq{c7t_o4>5oaUcObT%q#kEgI#iIeOw zzGQ@p+M{r!>{>u=Q-&X;Dh76nB7I`$^>{iwHI~n&^|dN~Z?F>;J|HJF__^g&dhbgo zDWz-sA>&rfNnsI27T6bxt7c+LL5|0UsT$7~@E-CJ?x*uV-i+E-$3HXRsXltd1?{6O z+Q*7K@u)7Pct+x!WS9gIHmnoc@#YOI*7$G~KeMWYN(%ih%tpb}iz0b?_nNl1KaVR+ z&3JZT@9bV$&EONumRjRh-0ap>t6KRjb_x_ZlS2HlAe=85`9VLule%?RFkl`z3nK9d zyw_BCwyb0ys%#skdvvsaB1w97;6usVQ2yHPvjRL>j{V=VU(u8kWaP;o1g0qOQ2WAjHL z{VLA#=skguHG2t{(5CO&W-Rvgii5`k1p*vaBmImqEcm%6yB&2Wvz<{F@{@{QEmgPk zAnO$r66%u0iQ2IOrV=ElQO|&i3u@W{Ox~&){=4kB(QL zUlX+r%R6h%ud3X}bsoB7LAsu|B<@UUj%}K(c6=%R-EUJ zyE>rQG7=wgS@Yd~<7VmyCv26p! z4ltY%E5cY}jCQ{LqA76WY!#X`qHlZnQ`>mqJL6}c{%0+kx{`40^FJE!OqFRP zu;vTS{bX(%a6`d>8}|0a1h}%%C`*zsGc|~LjNl$oqO+`2+`(iB7CQ`OjQ;Ch=3TOq zd=Mn~2v>fhVy@xdcG)^tHWZIX2KBcw^@>qokk<)S+~K8As@W}Jj42xh9%P|A)Q4Oa zv*!5)=&cu||Hqq{WPP0B(30Q&^2dJ?#Nfl=o$w4A<_|yo@!tk9n_yD%dlt>V_u(Hi z&tR;q&!YL&r$*DN3peh2yWckEXpQ?Y<+*;tSv;p`@f{pk+h2&s(jzY;w~Qoew0qV2 z4{1hS+MYoS;n#jSsK-6{DMFSszo8Q6U7|R|2ouVQM=z~nr(aK6TuMCdi157I8bWf4 z^+%AD=~0DxfZK`PUAE6E-0H&F0zMntw>4l}bsq z|5it!{QZyo&*m;Ym4Y=G7z*Q89n}uO?^8kf`5(v8v4UdRRP@ns5PBKMJr5hbO!&Li zsj_QGigScWd2?*YOTpK45F_Oq4-3@j_L$e%~ zp054aW~6^*Nw1K#T_ET?PiBOB_g03$lDF>GuF@!`+(^*mnWVp$Lw@&ze^Z{?YQe7Y WM}30qZX=)Y#+(JO|L~e>>)!!X3=Dn% literal 7365 zcmc&(30PCtwq7R#VJM=l8tXvlRiCra!J!Hyodm_IwN6)*q-sko4pc!@kaN`A)@lph z-d3=HV3lfX6;xCZB}XlyqJXFsWk{?-M1l-~kU%*5t$onGuYK*kefRUbFW*P@aMtjz zf9<{Y&f(J;(*oRG`?>;v`{cmaX9CEuD+6aKHi75L4`ZX7F?H4(m*U+@K7}!%GsnC? zv$6K(g{^RLE7V;5X8ht=w~owjv({&Q1>@hJX=yaIG}aIT20li^X>J|WX>>Z^xT@2U zb+e4G>=Crqs-L_wEKRk`}Aid;Mle7$x4Rw}G zS^|O~3>&s?{bysGd%g+KuVwPkGujDp|0rx8DjB)~QY?#ur(gR?5>AsAK7Z(Eb%z;dtpMOto zwD|UrL90KQLxlkhq#32$K!EGHb$*O-cz7iEJBIs(O}CKN+ubwV`MlUWUnFTDa0kGQ z82svv`5as`8NeAN9C-av1HfSd@ab4y?tC-e(*CD<`D<94xH zfV8qPe5*pQfT6R&;sMKTqjY!u_#15d0MPVv4X;*9kiIYUPRl0oU)@zhmO?Vt_LuO^ zB@QO-bf3nE$jHir2M$dCRs~;xm&@;dJ&j%w+>>hl%-%yrFvdYopy3SLWH1@F|EsSj zv(7~;zooI(V`6{s$}b`<&M<6^5DI}gn5bcE1;$HWtcJZtyMpWKOJMsZlL}@wI;0xc zT`UBi`TrIw&CSg%OkrW@dK;T#x1LVY`WxOYQp1lnt-XS=?A#!1wr4brGS0?$c9PH}J`3ahixLdN-rP*=US@X>Wb< zHDfDx7^<&O<$%}$B@@x$l>1F<7bBz#-S*v$c-tZ|R-&ERDq?Aiw;x3CPZtXb_BSl# z

nI6iV1>TX44dJZUZubu7N3fZjV<*#Dr4jkP-r`G{-Qs;0J#TH8E}Bz!kYZXGSe zhP{B!ucs5o_jc0T5BoQc5;t!+g6@Z}w|d7g*+z_UOtFB#U89X{#F~Cj3fri$2c=}) z7!}N0gWj*^symwkug8Gy4jTS`lrTjNnJuW9-O!rFFYZw)r=`j6mG; zY|&SwV3{|9??!Q*wng8N8*$`GA4b=b9d_0G^0Id+FU5kl9{PVEFAK%dnPMU1Yx3b7 zE(O`_Ybhm>O3)XRCHP2^Ags)R{;0MbM?I>VkCiy$k4VfIN6G$e`nmq#Q{tL=7g6@J zhEFIuP)r(>+_@hh8Z+@yRXPbau{4uAkCM94ppP1hYWLCPF7h0DqrsR<$#M_)3{7H| zOA%Rqf~DH&i<|LEEs4?J=$B+M6lF4I9H-_VS%eC2o)Ww&VG z6$;kU=}cR&APG<02UwjGgs{uRi#+E8U^MGnq=3M1I+RpUBVM>X zZ3}G-_xGwt25pkYf}M9zWJY;Ys&)QqA>gkJ*5BT2kQTbNnlyOaY}4nP*krYH7lIas zJ1ls4iN5a3jq&6=G@5oy$=0!J4P(h&(RYGSh?M=Ll{o<-HydDUSl3OFC! z73{W!5GTrv6nZC0+wR>4d>X~X z-(vsn#y>xoT7H;L&RW!Cuy<}jySkyU!^C!3jz?jHzCGvbuo zoQhICaB^ zsbUD8&9f1W#(IlAtN^DFO3-(qBpKL!B}|m9ooLQOqvqbG4qyC zxQ?f6GU#PVCYdX=es&@=E6v^KgF-He5DZo*tjM|WTwTeufZ+4Cm%P6 zu~Z!?9H6_CYZ9_<{-oqS5-sjj#6}m9!x+!#&VedO3={Xw&>UNECzb}%{8+UPRlB=s zDvuK6<;(eu#H%NFHk2ImhMm1xs)POJC(K(Rq3xv{%7o<)CjbX_JQ8&jjdjiPeK`D9B&2WV2T)Nv=lH>Bp4BLlA$xKp|L zuw-F-TPj&ajYzy&%!XQq`-0kFyjsnMx~@S_#;eUt;_dp{7fCC!JCxCsN%iFmpeR2? zF5`xSuV<*muvl=zZR#@t+V(B&)^Pl$L%D#F=$643N;btC!ss&}xV23$ShOFa>vtIE zycV`9VTDDz3Wu*S;Z}zF6|wmi#d9p6ju9+65!vzJm8-q}yz?*QK8Lo7J_wF~;1DI+%KdBAn7GhQ<8Rp*#mfASH+ zb(W-^56QGhA)gMUI@@WZlSNDYX<$;7n^h0CDnH!(ZdeQ@Ntapbdll0sd~oJPM*=n0 zk2^C*aw7OLTZ>P?r)WwVkwP^soV?G7jmvBFws9D=uDk4bHY6A3x%UU?6Xu?&>dG;ua5#AQN-R4UAX~79MEpVNF!?QMv^%Ee;EI$zoUQ21MGS|Pg`-(TP4nnUK z!1s=Kt$#=8GF4>VbYfy6Nv6DIW_-mbpx_?S@}XT%+v>bwK#ls&awBSa_QD`H2dtuqHy#BOKLGmn3h_+n5HN5%_xlPycpMWdD4g^lC_d*LjV_|gbzix+(3=q z?y+9XLBT-&%C{DFnP_#erobLAULvBEX(mTO7dtMEE2m25?G2S1 z#v?5USMrsn;;1MCQ5D3cUZF<`l+BJmN{QKCewD6_3-w|uWaGqC#{s2Dqw`3KgHY-= zCxD}dxdCg`qCifH=(nO9mE#6-)RNIzM>Aqe6k~p5!ajOL2B=UKe)MFDXzDfQ9!5I$ zvO0&0AuWoBA#`F?Yo#uS2A{TWTv-mqxW!L`n?zKNLseVhp{cs719=yaN*Y}t4hkc% zG(cK?;mb(N^%SmMY&#S37hgx)p_`j%#QG zQWdAZLR%9=cRV^0%n;*F?+%PT?7uGKLlbLe13JN$72qwNi)2 z9as#j4DRpYBK(Ct5C1Oq9wUB?Z&X{QP6Rs2>Q1lLKIBXn24vyma1q60z6v+ImMx-q zXu2hm9Q=^&wM=xwhk$G_2~x|RVgdJ z2R@1BH?Ji-v(DA7NxNqIL(F#3w zb>~4=w0I(L6?R&?x8oZXb1+qSBVplXJzkTbq|{1^CwAcf7+|*+ ze!%+4ZP7lM?x|=jZ~QBxF*Cd;9y?nqp$sX-BJ65Bu?_TC&(p#zhfXFRyBi1lf4V!e zek{Cx5C*}IA(APurHYyIKU|>N@4i5naNs4r3ICnu-+Q_4@&_;FF#y2J3I5FdosJ9` z4L{P4+3ApT zpGQ}0;c8oqpLm1W*fad0U~rnIB<*gHTPrk0_-orE{MGFby#HvI{oxz>m)>I)wy{A@ Ut2<89`vOdUW7_M7Ue#^-Z@Bdv{r~^~ diff --git a/brand/projects/modern-di-aiogram/mark-512.png b/brand/projects/modern-di-aiogram/mark-512.png index 586c7b4cb03415cef006899890090833555e0c9f..11007b74695a95c768447e8b4b178e49ef88125d 100644 GIT binary patch literal 3264 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 G$6o + diff --git a/brand/projects/modern-di-celery/lockup-dark.svg b/brand/projects/modern-di-celery/lockup-dark.svg index c9fb754..275dcea 100644 --- a/brand/projects/modern-di-celery/lockup-dark.svg +++ b/brand/projects/modern-di-celery/lockup-dark.svg @@ -1 +1 @@ - + diff --git a/brand/projects/modern-di-celery/lockup-light.svg b/brand/projects/modern-di-celery/lockup-light.svg index 319523f..558743a 100644 --- a/brand/projects/modern-di-celery/lockup-light.svg +++ b/brand/projects/modern-di-celery/lockup-light.svg @@ -1 +1 @@ - + diff --git a/brand/projects/modern-di-celery/lockup.png b/brand/projects/modern-di-celery/lockup.png index 45981eebc3d75bc9cdc0db0783ebd360098282d8..2dc93cb067472fe908d4e0c8909f80a77735029d 100644 GIT binary patch delta 1696 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 diff --git a/brand/projects/modern-di-celery/mark-1024.png b/brand/projects/modern-di-celery/mark-1024.png index 08801b15eaaa59b61a29953f8e221d6271905ad5..438161ef0e7bea26b04ffce81f94d4419dfcceee 100644 GIT binary patch literal 6057 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 qZ)HC;{%_vY7=mDU<%3&VCJ*ZCM literal 5941 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 N0)rNPvXFoE{{X3)_qG54 diff --git a/brand/projects/modern-di-celery/mark-512.png b/brand/projects/modern-di-celery/mark-512.png index 7008e573063f15ab7e329214ad2e5fde9f03af68..0859af7e9b7131b10666f524d90f3597db713a8e 100644 GIT binary patch delta 1441 zcmXYxdrVVz6vxlKeetp&P%EI71hFD2gn%HAQXDvy2?$jYQHnSRQ?afTkWu=Z6LsJO z)+r8gRObV+0VYnnYUB!;4_<-}MJmv(D$ha*?^o||@sphMP0l~xUw?rl>wVAQ@t*9}Kb-lssykyaRLy<$7h6A`liV%C0Ov!D31E&uMPLQK zY2sN`=`Gy?U^S2*Dj(!|gKg(vv?y-<=>-G+gzt8Qm*XrCE zl__$CE&3Jzm;hmX%?p@TF%)f`Ql$}qsG57YgJ|`Gx$1Ji z&UxPHcpaFOVc?EMF^DLgrFi%y*(2m!|J-s~Y^E@=#^DMU`@DC? zTkL^G3&|AdNF+;m=1MF6L9%BjdNnz*^(G9INLfO1Uu%P!+28ZMAS^)wJXvN& zcG`(D%-yRMOP{gdiT?pTMSU=P_t7pQeG4WsnlyJ?O2(dqD-B6wp?qiXy)hg9fI8p- zlNQ<+g~%7uvFO>Qm*>?+I2_7n!Qfl!-b^=z8FbQOvivH|APg(4c8Z`Nc|l3Q0wsqK zzI*=!*@F+R^r8PP1Hy~Q=|^UuG9QghlTbwL(p|&yZ7eWstMuYxED)JBD<`jurXZER zSIkvp!XTwOwiVveV9ejNqXWsUrNG)cKtqEL$W!Mn$*3hBY9Jf&gG*VfZDg+9Jiy1R$AqpEc0vc!Yk; zuTAraXZ2!|zljFrdQGtWFl{BaMt+{QR;C(%x;XF5aC7O~QycaE>zWdD9+1LW^2?ld zQ{LGHvJ_?B$!mfB?K&MP22~TT4Y*uy2@=e3p2*$_t(Zz|FM4CjKMcime;=&P8F$p~ zz9C%>+~e#^*bWnfa>FoJDxV1HMl9S>aje(j(K(7}#iV?QvfUgZgKQ@nNz2aM=PjyY zeT;acdYXxT!bTh0r)}UpexYcr5p2yB2k(~B6apAo0U5A`=AMiz?AptU_Q4@BHR5-O zx%eez@gchWIm1Q1596nfbL?qEXMzse3Juz)VR33#CUNJPu{9tdx9a#QO$kz3RdM+59rrQv*-?>B{Hjv}Pw U3vz1voME2LAz{Jg8-&OI15~$qyZ`_I delta 1432 zcmYk6Yc!Mz7{{OY9dpGDF%*WWJ-cK(XrqYb%?YXFPHM5HUDZUGN;lEGx*Vx2HAO9n zQ&*m6lTqfSSWq_zne-d65p6Js`J-nAe0oc(|KfB65O=hO529xZEFmb=>CMHo6e z`@Z9fS$z(WB#fT}XJP2b>(cI;Fc)D6hGUpOF#Bn=J(qcD^Lp`Bx5DE9z)uMc3`;a5 zsR%8PB-`{DZ_D&Sr_(u`ntG7Bx@|sIUZwf!wJEe*``dW#e4LLn! zYIk>NYr~eTQj&C>aAKWVd$8s5Q^B;0eB`s}l}oLIOn4|b#gb%#5ug|_0O5lk4lhez z4+kb~-%wxz+~=guRsO&PO68u``S+0G(WGBm$EonwgibqfR3EEN-&ox>03WPjt1H7} zhMbnjes9yY&ObqRjB(zQ=_r3`wnv3Zb|D8PB7`00$H_*C(b@wENO$3#arJ1+rHF^h z7?sK%lECg>*dt@WAJ?R(&JM%U?uJSofTB*@7_R7`Lt9eaC`#NvBR9fFV)c@e`#Yn^ zVfAA~vI+H+c%l{(G0I?YuvuLI9h;SWLZdHJ0xnay;_MNcvdh&R(}({QY=u`Rv{$|J z(%K&8f#Xy^J4~F!noj%JS~4Zm`467Cr?6 zny`y4zkG8C!81wCW2HP)F&Wizw%I(_m5lJqXhP1s5W8*aLqu-spn&}p5NDP!t8?ft z=K@k0SdfhJwNu&Czt8>7Vhlqw;b3Bl6{@#=U1N*qepK1YbDKlAae)#%3Z#h_-r$#tMH zAo}w0jc^RPrsb6^xrso%4dcR*B(zgz9!!O4v_sC@L4|Vs^MLVhh(h_avxv5xBXF8o z{24O@E5yu-5)Xuhpye<|g+8h{wIW8f(Lo%Lm_qdoD58Toxo zI~#mK;TY)x^%-U=mc0#r0r$yAhA1K%>CTz!_zcp(icaA%0Jxy3uP*vqI{(0i%%3(J zVA$CxhCE-sYm+UTF~B?PWF9EC(*;0kk6S|~*k%N-LStx626_PXr&KKUp4<(mn|YH{ z0vpD@H2!TAWXqLtk`q)rq(gF>>LBj+_4sah&@bnr|H-(EnZ6w-e=-1TOFB;XLy4~1 z-Lcf>#%afq#R^W2TBB*@z`HfjZ_=cLU~@=jMjxjJ^Y9x%=VFhd!In^tZ~{S{1q_W+ zZNyY$5fOWFF3KnFgeh2vk?4(^;4CnNKYsBQ4M8DO_hA8hBS!iBMJ_QDv+}0#a~iR5 zswEO(Q+nnRnS8C2##iW!w_i|vU>F$^GjHc)98*Jn9(Drw*A*ho_fR;Dc3UZ{EIa$@ zTWBJ3Z{S{1Cqeq;Y=f&SU4sTSPv0kwv%w>)m{%@Kqm7)j=>1qZktq)KI#M&&zwZ*r zHjT1+y(gM%JtykrixMR*6;Vq<=(2Druk3S`e7=tp1?TBbg$2}XcR0Uv#lP;J95?=_eEOa2d-)>Po&PK?)LC#T9;A*+Z)--r=lHj zE*oWo4`s(1L2p5$5Hjz_I+2Yo2gksn{M6tdo$=0M?!OTGKhg5$Y;tyGc|VJoJp3;L N{Cxs9S9=Ri{R1y_cf|kz diff --git a/brand/projects/modern-di-celery/mark.svg b/brand/projects/modern-di-celery/mark.svg index ac9816c..0582ebf 100644 --- a/brand/projects/modern-di-celery/mark.svg +++ b/brand/projects/modern-di-celery/mark.svg @@ -1 +1 @@ - + diff --git a/brand/projects/modern-di-taskiq/lockup-dark.svg b/brand/projects/modern-di-taskiq/lockup-dark.svg index b929362..d2e29f9 100644 --- a/brand/projects/modern-di-taskiq/lockup-dark.svg +++ b/brand/projects/modern-di-taskiq/lockup-dark.svg @@ -1 +1 @@ - + diff --git a/brand/projects/modern-di-taskiq/lockup-light.svg b/brand/projects/modern-di-taskiq/lockup-light.svg index 4da500a..c768627 100644 --- a/brand/projects/modern-di-taskiq/lockup-light.svg +++ b/brand/projects/modern-di-taskiq/lockup-light.svg @@ -1 +1 @@ - + diff --git a/brand/projects/modern-di-taskiq/lockup.png b/brand/projects/modern-di-taskiq/lockup.png index a33093af09e29063fdf8e08d6cebf1e749946cd4..72f1c50967667bfb4ae1ba80b8ce05920540c4ae 100644 GIT binary patch delta 1842 zcmZ9NX*k=77RICLNEu>Oiy@^Wv?!WTOD<~PW-Nm$+8~c5YKxNEZX%(BOzc{%#9Boe zt>D%!D)zLZQMDJXW&S#LLe-k9^JVUH&vU-K&-*(c&X@Pi6Wf4hs$|)zliA6j*Hn<2 zo15lcM`H{I6c?w3#kR+R_$SK;xwyEz%LW<88H4_3-e=~noXCs!oa~)JN5_=-flvv% zt2IMX4v3H%2=vUU?;xiHz>w45POf}dAb>!EMKp}Ff z5pi0m@A0&bhkGR1?x0N)h4|Rb#MxVgmOt}MgwaAVr1f<0^4gV5Fpmh>MG$K$JuIP| zm-MJU$7RVZFwYi{|1+%f4fnf+1Ff8yArG0SdA>3e4Wdjo@$8x2ds^kORxi`vpruRK|qAtX_S7K@0T*jlCWQZq`*#TiJW=`715e?$vsSVczw%0hX zA2wOipF^x7edLm2_QZcS>Tizsl>4aMz^>NAWx>0Pu%uo>I`4e~Vg)O>e;b)oOoOIZ zWaUTON2M(8C>n@0knliHSFQ0@Xhe$q+m8<&O2EK@rjcEF{h`yX(=M}N>dr}esgDL#bN=k`rQ2t*9|23Y!mA z_dlKdw@!^_aDQ!zCUH~M$!n6U>JXN_?v!n0Ux}@_JD_J<_E?Czox~Lm5WW_er=cl- z?nx;c>BKlXDdhLt_OOBY@k)I8dH6=`4h=I}$lH5}DBsFdh$*5ZhGJ`XO05q@)pO}@iJlO5s zgW**)n6<0(X!2)OWg(>mNq_Ys>j!#nRo2kIM7-NtgRyd>oq1HzzbeNc?PaD||5hsc z`p_hri;Rj)GtSnSlzVaA|OSFzzrGIOYm@s7wO(2;LD)|gL^PlF+=C`6Hkn5>K?B=CMq4dxmI5p3%}gJXzxdTUj1d4 zI>Ww+EV{0akbNJ7DI6fK#aSL9hWl}6uOPhoiL3W e3oF|bf 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 literal 8289 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 diff --git a/brand/projects/modern-di-taskiq/mark-512.png b/brand/projects/modern-di-taskiq/mark-512.png index 006bed6f0ad9d75b307329a3d8854971a58003c2..93d453db37409c0854384285ac02d77ec7b6d39e 100644 GIT binary patch literal 3354 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 + diff --git a/planning/changes/2026-07-12.01-seven-new-project-marks.md b/planning/changes/2026-07-12.01-seven-new-project-marks.md index 652bc9e..ca0b54c 100644 --- a/planning/changes/2026-07-12.01-seven-new-project-marks.md +++ b/planning/changes/2026-07-12.01-seven-new-project-marks.md @@ -51,7 +51,7 @@ fills with `CREAM` knockouts, so `test_only_allowed_colours` passes unchanged. | `modern-di-celery` | `celery_stalk` | Celery's icon redrawn: banded capsule + right-facing open C | | `modern-di-flask` | `flask_horn` | Flask's literal `flask-icon.svg` path, recoloured | | `modern-di-grpc` | `rpc_arrow` | a symmetric bidirectional arrow | -| `modern-di-taskiq` | `task_q` | taskiq's Q-creature: thick ring, eye, crossing descender | +| `modern-di-taskiq` | `task_q` | taskiq's Q-creature: thick ring, crossing descender | | `compose2pod` | `pod` | Podman's heptagon holding three composed containers | Two of these need explanation. @@ -133,3 +133,14 @@ committed. terms, the horn is one function to redraw. - **Low: stray colour fails the palette test.** All seven use only `GOLD` and `CREAM`; `test_only_allowed_colours` is the guardrail. +- **Medium (realized, fixed): CREAM must only knock out of GOLD, never sit + directly on the transparent background.** Marks render on dark surfaces too + (`lockup-dark.svg` is the dark half of every README `` banner), so + standalone cream ink — invisible on a cream/light page — becomes bright + white ink on dark. Three of the seven symbols shipped this bug (`task_q`'s + eye sat in the ring's hollow counter with no gold beneath it; `celery_stalk`'s + bands poked past the capsule's curved cap; `plane`'s round-capped crease + spilled past the hull at the nose) and were fixed in a follow-up pass, with + `test_new_marks_have_no_cream_on_transparent` added as the regression guard. + The durable lesson: composite every new mark onto a dark background before + it ships, not just a light one. diff --git a/tests/test_projects.py b/tests/test_projects.py index ed0f1c5..699aa43 100644 --- a/tests/test_projects.py +++ b/tests/test_projects.py @@ -2,9 +2,11 @@ from pathlib import Path from xml.dom import minidom import pytest +from PIL import Image from brand.build import geometry as g from brand.build import tokens as t from brand.build import projects as p +from brand.build.raster import export_png def test_project_frame_parses_and_uses_tokens() -> None: @@ -160,3 +162,76 @@ def test_render_projects_writes_cards_for_docs_repos_only(tmp_path: Path) -> Non non_docs = set(p.MANIFEST) - DOCS_EXPECTED for repo in non_docs: assert not (tmp_path / repo / "social-card.svg").exists() + + +# Regression guard for the transparent-background invariant: every mark is +# drawn on a transparent background, and CREAM is only ever a knockout +# painted ON TOP OF a GOLD shape — never standalone ink directly on the +# background. Violate that and the mark looks fine on a cream/light page +# (cream-on-cream is invisible) but shows stray bright-white ink once the +# same mark.svg is placed on a dark surface (e.g. lockup-dark.svg's README +# banner half). Only the seven marks introduced on this branch are checked +# here — see NEW_MARKS below. +# +# Known, pre-existing, OUT OF SCOPE exclusions: `db-retry` and +# `faststream-outbox` both use the `_cyl` helper, whose 0.8-wide CREAM rim +# stroke straddles an ellipse edge and leaves a faint cream hairline outside +# the gold — the same class of bug, shipped before this branch. Fixing +# `_cyl` is a separate follow-up; it is deliberately not touched here. +NEW_MARKS = { + "modern-di-aiogram", + "modern-di-arq", + "modern-di-celery", + "modern-di-flask", + "modern-di-grpc", + "modern-di-taskiq", + "compose2pod", +} + + +def _cream_pixels_without_gold_beneath( + repo: str, tmp_path: Path, size: int = 256 +) -> list[tuple[int, int]]: + """Rasterize `repo`'s mark twice — once normally, once with every CREAM + knockout stripped to `none` — and return the (x, y) of every pixel that + is CREAM in the normal render but transparent once CREAM is stripped. + Such a pixel has no gold underneath it: it is standalone cream ink + sitting directly on the transparent background.""" + svg = p.project_mark(repo) + normal_svg = tmp_path / f"{repo}-normal.svg" + normal_svg.write_text(svg, encoding="utf-8") + normal_png = tmp_path / f"{repo}-normal.png" + assert export_png(normal_svg, normal_png, width=size, height=size) + + stripped_svg = tmp_path / f"{repo}-stripped.svg" + stripped_svg.write_text(svg.replace(t.CREAM, "none"), encoding="utf-8") + stripped_png = tmp_path / f"{repo}-stripped.png" + assert export_png(stripped_svg, stripped_png, width=size, height=size) + + normal_im = Image.open(normal_png).convert("RGBA") + stripped_im = Image.open(stripped_png).convert("RGBA") + cream_rgb = tuple(int(t.CREAM[i : i + 2], 16) for i in (1, 3, 5)) + tol = 10 + bad: list[tuple[int, int]] = [] + for idx, ((r, gg, b, a), (_, _, _, sa)) in enumerate( + zip(normal_im.getdata(), stripped_im.getdata()) + ): + if a < 200: + continue + if ( + abs(r - cream_rgb[0]) < tol + and abs(gg - cream_rgb[1]) < tol + and abs(b - cream_rgb[2]) < tol + and sa < 50 + ): + bad.append((idx % size, idx // size)) + return bad + + +@pytest.mark.parametrize("repo", sorted(NEW_MARKS)) +def test_new_marks_have_no_cream_on_transparent(repo: str, tmp_path: Path) -> None: + bad = _cream_pixels_without_gold_beneath(repo, tmp_path) + assert not bad, ( + f"{repo}: {len(bad)} cream pixel(s) with no gold beneath, e.g. {bad[:5]} " + "— this mark will show stray white ink on dark surfaces" + ) From a85bf323a152599ee024543a3246062dc89364b7 Mon Sep 17 00:00:00 2001 From: Artur Shiriev Date: Mon, 13 Jul 2026 08:43:27 +0300 Subject: [PATCH 09/10] fix(brand): close the cream-on-transparent guard's coverage gap and relax the plane's fold crease Address re-review findings on the first cream-on-transparent fix wave: parametrize the regression guard over every manifest repo instead of a frozen seven-repo allowlist (so a future repo can't silently ship standalone cream), xfail the two known pre-existing db-retry/ faststream-outbox hairlines explicitly, record the transparent-canvas invariant in architecture/brand-marks.md where it previously said nothing about it, harden the guard's cream-strip against a silent no-op, and skip (rather than hard-fail) the guard when rsvg-convert is unavailable, matching test_assets.py's convention. Also relax modern-di-aiogram's plane crease: the fold-end inset was over-inset to match the nose end even though the fold vertex is the polygon's reflex vertex with ample clearance, making the crease read as a floating stripe. Per the repo owner's ruling, reduced the fold-end inset to 0.05*r (nose-end inset unchanged) so the crease runs notch-to-nose again; still verified inside the gold by the guard test. Co-Authored-By: Claude Opus 4.8 (1M context) --- architecture/brand-marks.md | 10 ++- brand/build/symbols.py | 23 +++++-- .../modern-di-aiogram/lockup-dark.svg | 2 +- .../modern-di-aiogram/lockup-light.svg | 2 +- brand/projects/modern-di-aiogram/lockup.png | Bin 2054 -> 2066 bytes .../projects/modern-di-aiogram/mark-1024.png | Bin 7341 -> 7443 bytes brand/projects/modern-di-aiogram/mark-512.png | Bin 3264 -> 3293 bytes brand/projects/modern-di-aiogram/mark.svg | 2 +- tests/test_projects.py | 60 ++++++++++++------ 9 files changed, 71 insertions(+), 28 deletions(-) diff --git a/architecture/brand-marks.md b/architecture/brand-marks.md index 0acd72e..49bfd8b 100644 --- a/architecture/brand-marks.md +++ b/architecture/brand-marks.md @@ -20,7 +20,15 @@ dimensions in `render.py`. One large-format logo per repo: the constant green+gold snake-frame (`geometry.py::project_frame`, margin 9 / arm 53 / stroke 11) with a single 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 +Two-colour (green + gold); repos differ by symbol shape, not colour. Every mark +renders on a transparent background, so `CREAM` is only ever a knockout painted +ON TOP OF a `GOLD` shape, never standalone ink directly on the background: +standalone cream is invisible on light surfaces (cream-on-cream) but shows as +stray bright-white ink once the same `mark.svg` sits on a dark one, e.g. +`lockup-dark.svg`'s README banner half. Enforced by +`tests/test_projects.py::test_new_marks_have_no_cream_on_transparent`, which +rasters every manifest repo's mark with its cream knockouts stripped and fails +on any pixel that turns transparent instead of staying gold-backed. The two project templates reuse the org chevron. Two marks are built from a partner's literal logo path, recoloured: `modern-di-faststream` (FastStream's) and `modern-di-flask` (Flask's horn — the Flask Artwork License permits the logo diff --git a/brand/build/symbols.py b/brand/build/symbols.py index 87484f2..cae20e2 100644 --- a/brand/build/symbols.py +++ b/brand/build/symbols.py @@ -416,16 +416,27 @@ def plane(cx: float, cy: float, r: float) -> str: hull = ((-0.95, 0.02), (0.95, -0.78), (0.30, 0.86), (0.02, 0.28)) body = " ".join(f"{cx + dx * r:.1f},{cy + dy * r:.1f}" for dx, dy in hull) # Crease runs fold-point -> nose (hull[3] -> hull[1]), a chord that meets - # the hull exactly at those two vertices. Inset both ends off the - # vertices (and use a butt cap, not round) so the stroke's own width - # can't spill past the polygon at the nose's sharp point. + # the hull exactly at those two vertices. Use a butt cap, not round, so + # the stroke's own width can't spill past the polygon. + # + # The two ends need different insets. hull[1] (nose) is a sharp, + # non-reflex vertex — a butt cap placed at the vertex itself pokes the + # 0.11*r-wide stroke past both adjoining edges, so it needs a real inset + # (~0.154*r is the minimum for this vertex's angle; 0.20*r keeps margin). + # hull[3] (fold) is the polygon's REFLEX vertex (interior angle ~229deg), + # and the crease direction sits ~23deg clear of the nearest edge, so a + # butt cap placed essentially at the fold vertex already stays inside the + # gold (~0.021*r of margin) — only a token inset is needed there. Insetting + # it as much as the nose end made the crease read as a floating stripe + # instead of a fold running notch-to-nose. fold, nose = hull[3], hull[1] ex, ey = nose[0] - fold[0], nose[1] - fold[1] elen = math.hypot(ex, ey) ux, uy = ex / elen, ey / elen - inset = 0.20 * r - x0, y0 = cx + fold[0] * r + ux * inset, cy + fold[1] * r + uy * inset - x1, y1 = cx + nose[0] * r - ux * inset, cy + nose[1] * r - uy * inset + inset_fold = 0.05 * r + inset_nose = 0.20 * r + x0, y0 = cx + fold[0] * r + ux * inset_fold, cy + fold[1] * r + uy * inset_fold + x1, y1 = cx + nose[0] * r - ux * inset_nose, cy + nose[1] * r - uy * inset_nose crease = ( f'' diff --git a/brand/projects/modern-di-aiogram/lockup-dark.svg b/brand/projects/modern-di-aiogram/lockup-dark.svg index 9d62a05..2286676 100644 --- a/brand/projects/modern-di-aiogram/lockup-dark.svg +++ b/brand/projects/modern-di-aiogram/lockup-dark.svg @@ -1 +1 @@ - + diff --git a/brand/projects/modern-di-aiogram/lockup-light.svg b/brand/projects/modern-di-aiogram/lockup-light.svg index f934ea3..f3a55e9 100644 --- a/brand/projects/modern-di-aiogram/lockup-light.svg +++ b/brand/projects/modern-di-aiogram/lockup-light.svg @@ -1 +1 @@ - + diff --git a/brand/projects/modern-di-aiogram/lockup.png b/brand/projects/modern-di-aiogram/lockup.png index 3454ba3e3ebb84e1bf11fdaf2df867d1902f88a2..bb07cbb2de3204c405140b3db84118871fe4c983 100644 GIT binary patch delta 1984 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 literal 7341 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 WM}30qZX=)Y#+(JO|L~e>>)!!X3=Dn% diff --git a/brand/projects/modern-di-aiogram/mark-512.png b/brand/projects/modern-di-aiogram/mark-512.png index 11007b74695a95c768447e8b4b178e49ef88125d..60bba14e5f457787ab76b1c2b6295c4db9ab1190 100644 GIT binary patch literal 3293 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 + diff --git a/tests/test_projects.py b/tests/test_projects.py index 699aa43..938726f 100644 --- a/tests/test_projects.py +++ b/tests/test_projects.py @@ -1,4 +1,5 @@ import re +import shutil from pathlib import Path from xml.dom import minidom import pytest @@ -170,23 +171,33 @@ def test_render_projects_writes_cards_for_docs_repos_only(tmp_path: Path) -> Non # background. Violate that and the mark looks fine on a cream/light page # (cream-on-cream is invisible) but shows stray bright-white ink once the # same mark.svg is placed on a dark surface (e.g. lockup-dark.svg's README -# banner half). Only the seven marks introduced on this branch are checked -# here — see NEW_MARKS below. +# banner half). Parametrized over EXPECTED_REPOS (the full manifest, like +# every other guard in this file) so a repo added later is covered +# automatically instead of needing to be opted in. # -# Known, pre-existing, OUT OF SCOPE exclusions: `db-retry` and -# `faststream-outbox` both use the `_cyl` helper, whose 0.8-wide CREAM rim -# stroke straddles an ellipse edge and leaves a faint cream hairline outside -# the gold — the same class of bug, shipped before this branch. Fixing -# `_cyl` is a separate follow-up; it is deliberately not touched here. -NEW_MARKS = { - "modern-di-aiogram", - "modern-di-arq", - "modern-di-celery", - "modern-di-flask", - "modern-di-grpc", - "modern-di-taskiq", - "compose2pod", -} +# db-retry and faststream-outbox carry a faint standalone-cream hairline from +# _cyl's 0.8-wide rim stroke straddling an ellipse edge — the same class of bug, +# pre-existing and out of scope for this change. strict=True means the day _cyl +# is fixed, these turn red and force this exclusion to be removed. +KNOWN_CREAM_ON_TRANSPARENT = {"db-retry", "faststream-outbox"} + + +def _cream_guard_params() -> list[object]: + return [ + pytest.param( + repo, + marks=pytest.mark.xfail( + strict=True, + reason=( + "known pre-existing _cyl rim-stroke cream hairline; " + "see KNOWN_CREAM_ON_TRANSPARENT" + ), + ), + ) + if repo in KNOWN_CREAM_ON_TRANSPARENT + else repo + for repo in sorted(EXPECTED_REPOS) + ] def _cream_pixels_without_gold_beneath( @@ -203,8 +214,18 @@ def _cream_pixels_without_gold_beneath( normal_png = tmp_path / f"{repo}-normal.png" assert export_png(normal_svg, normal_png, width=size, height=size) + stripped = svg.replace(t.CREAM, "none") + # A literal, case-sensitive replace silently no-ops if cream were ever + # written in a different form (e.g. uppercase hex, rgb()) — make that + # loud instead of letting the guard pass vacuously against an unchanged + # (still-opaque) render. + if t.CREAM in svg: + assert stripped != svg, ( + f"{repo}: stripping {t.CREAM} left the SVG unchanged — " + "the guard would compare a render against itself" + ) stripped_svg = tmp_path / f"{repo}-stripped.svg" - stripped_svg.write_text(svg.replace(t.CREAM, "none"), encoding="utf-8") + stripped_svg.write_text(stripped, encoding="utf-8") stripped_png = tmp_path / f"{repo}-stripped.png" assert export_png(stripped_svg, stripped_png, width=size, height=size) @@ -228,7 +249,10 @@ def _cream_pixels_without_gold_beneath( return bad -@pytest.mark.parametrize("repo", sorted(NEW_MARKS)) +@pytest.mark.skipif( + shutil.which("rsvg-convert") is None, reason="rsvg-convert not installed" +) +@pytest.mark.parametrize("repo", _cream_guard_params()) def test_new_marks_have_no_cream_on_transparent(repo: str, tmp_path: Path) -> None: bad = _cream_pixels_without_gold_beneath(repo, tmp_path) assert not bad, ( From 710ebebee0cd0f62dddd5e3b2cbb4e7c77109194 Mon Sep 17 00:00:00 2001 From: Artur Shiriev Date: Mon, 13 Jul 2026 09:15:18 +0300 Subject: [PATCH 10/10] fix(brand): inset _cyl's cream rim so no mark paints cream on transparent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit _cyl stroked its cream rim centred on the top cap's ellipse, but that ellipse's upper arc is the cylinder's silhouette — so half the 0.8-wide stroke fell outside the gold. Invisible on cream, a stray white hairline on dark. Shrink the rim's radii by half the stroke width so the whole stroke lands inside the cap. This was the last exemption in the cream-on-transparent guard: db-retry and faststream-outbox were strict xfails. The guard now covers all 26 marks with no exemptions, and is renamed test_no_cream_on_transparent since it is no longer scoped to the new marks. Co-Authored-By: Claude Opus 4.8 (1M context) --- architecture/brand-marks.md | 10 +++--- brand/build/symbols.py | 18 ++++++++--- brand/projects/db-retry/lockup-dark.svg | 2 +- brand/projects/db-retry/lockup-light.svg | 2 +- brand/projects/db-retry/lockup.png | Bin 1531 -> 1521 bytes brand/projects/db-retry/mark-1024.png | Bin 10371 -> 10408 bytes brand/projects/db-retry/mark-512.png | Bin 4602 -> 4581 bytes brand/projects/db-retry/mark.svg | 2 +- .../faststream-outbox/lockup-dark.svg | 2 +- .../faststream-outbox/lockup-light.svg | 2 +- brand/projects/faststream-outbox/lockup.png | Bin 2026 -> 2029 bytes .../projects/faststream-outbox/mark-1024.png | Bin 7898 -> 7963 bytes brand/projects/faststream-outbox/mark-512.png | Bin 3384 -> 3386 bytes brand/projects/faststream-outbox/mark.svg | 2 +- .../faststream-outbox/social-card.png | Bin 14030 -> 13946 bytes .../faststream-outbox/social-card.svg | 2 +- .../2026-07-12.01-seven-new-project-marks.md | 10 ++++-- tests/test_projects.py | 29 ++---------------- 18 files changed, 35 insertions(+), 46 deletions(-) diff --git a/architecture/brand-marks.md b/architecture/brand-marks.md index 49bfd8b..bfac012 100644 --- a/architecture/brand-marks.md +++ b/architecture/brand-marks.md @@ -25,10 +25,12 @@ renders on a transparent background, so `CREAM` is only ever a knockout painted ON TOP OF a `GOLD` shape, never standalone ink directly on the background: standalone cream is invisible on light surfaces (cream-on-cream) but shows as stray bright-white ink once the same `mark.svg` sits on a dark one, e.g. -`lockup-dark.svg`'s README banner half. Enforced by -`tests/test_projects.py::test_new_marks_have_no_cream_on_transparent`, which -rasters every manifest repo's mark with its cream knockouts stripped and fails -on any pixel that turns transparent instead of staying gold-backed. The two +`lockup-dark.svg`'s README banner half. Enforced for **every** manifest repo, with +no exemptions, by `tests/test_projects.py::test_no_cream_on_transparent`, which +rasters each mark with its cream knockouts stripped and fails on any pixel that +turns transparent instead of staying gold-backed. `_cyl`'s cream rim is inset by +half its stroke width for exactly this reason — centred on the top cap's ellipse, +half the stroke would have fallen outside the cylinder's silhouette. The two project templates reuse the org chevron. Two marks are built from a partner's literal logo path, recoloured: `modern-di-faststream` (FastStream's) and `modern-di-flask` (Flask's horn — the Flask Artwork License permits the logo diff --git a/brand/build/symbols.py b/brand/build/symbols.py index cae20e2..c63ae40 100644 --- a/brand/build/symbols.py +++ b/brand/build/symbols.py @@ -23,12 +23,20 @@ def _cyl( ) -> str: """Database cylinder centred on (cx,cy).""" rx = 0.5 * r * w + ry = 0.16 * r + top = cy - h / 2 * r + # The top cap's upper arc IS the cylinder's silhouette, so a rim stroke + # centred on that ellipse would put half its width outside the gold — + # invisible on cream, but white ink on dark. Shrink the rim's radii by half + # the stroke width (plus a hair of margin) so the whole stroke lands inside. + rim_w = 0.8 + inset = rim_w / 2 + 0.1 return ( - f'' - f'' - f'' - f'' + f'' + f'' + f'' + f'' ) diff --git a/brand/projects/db-retry/lockup-dark.svg b/brand/projects/db-retry/lockup-dark.svg index be22819..9ae1b9f 100644 --- a/brand/projects/db-retry/lockup-dark.svg +++ b/brand/projects/db-retry/lockup-dark.svg @@ -1 +1 @@ - + diff --git a/brand/projects/db-retry/lockup-light.svg b/brand/projects/db-retry/lockup-light.svg index ad84956..7ad437d 100644 --- a/brand/projects/db-retry/lockup-light.svg +++ b/brand/projects/db-retry/lockup-light.svg @@ -1 +1 @@ - + diff --git a/brand/projects/db-retry/lockup.png b/brand/projects/db-retry/lockup.png index 9b04bac56a09aca32a0192da4b5a90f68a8cac75..eda26a3e13ee44105761a275097f6f66c257c802 100644 GIT binary patch delta 1452 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 Q4*&oF07*qoM6N<$f&m}cod5s; diff --git a/brand/projects/db-retry/mark-1024.png b/brand/projects/db-retry/mark-1024.png index 280503879c32013b88f77390e6c412f0e003d03a..d5d4e8b95d3ca88ab4b1e13856db2f1997b0c149 100644 GIT binary patch literal 10408 zcmb_?2Ut|ew(i>9O=xnIB*B2FL>&nUN5+rpaA|hZjf`F1*kt{)*)X?4gR?oTjz5C9adFQ_Ko$u@3p{iE;*Q%;jRr?1Q zCwo~bO(_77-R|(sZU72;q<|zD-5hGW3ek=3vUBe?^P{`XkL@00XO>%af2Vl^#{hKX&qu!18jNRzkm{Ra@8|9dMpe<%Ok;ZAS93K<00TFO zQsz;1x*GV+aQid?Ud~nXs?L8R15IOLX71|~O90HDV00~j(HonAzcG@6(eA3jKoe6R zplyo8QUch~({&X>RH7__$#-42eRYtSD?K-V3|>ap=o_4d6l>AFb1db)F5f_72baNf-`vX#jWBb0$tUMD^7n>px|AAj zVQW&g#^{I;qf@8s!(QLh?!vY;*?|#O{aA-9FK8g_8*x5Y9vpGg*0lb<;~L2^h~3YN zb$aiep~AI$rc6(72=Pl2?hUCiz#mq$X?RdSrZd2ewDcrte)M40s-ZJa{?I5f6N2XL zoyep|NI-dcwfe1F%B-MP<0~7($?@D#86df!GI3`Hi^4#&%oVD}4 zA9ig(?{QQ!H6A-GlKv}d-0z4Nx20>_AH>!mwLDs##Z1MxgFDS?kQM&CyPV@D3%*AW zVu@@!xZz2fK1*~3h%H6(kDa2LEnRS~_;ljZ2ZyN^k=ThnHU0W{;AM(@CIiC9ZB;kd zm$kk<#X8NE$4{n$f7AM`; z&cIhoutX6K8?&W!K8y!i%30D8)PqX&N=ju-&2l<{NYk%Sn%C_M^XBv-5&3m_XFBf8 zSuQ>=$V7k{n_wwr#I1(q^bXWA!4W@xIW{t(ie-c9WKFPz&Re`JTw8=}n6sGt@4+D_ zH46Gf;>YiDJ}WV{_phfvM1*0E_>*%IOEbhjiJ%Ll7PP;=o_=QbIs-P8P~2Yg{o8Aa zO&dukQ9<}F8`aJFi=2#(0lyVF^CHvQ)Dl(-IxD9eRfLu|zo3#mj`;M7ushgHZz!{LD{T_*p7FS}fPCar z8SQOjfZJ88sB4R>AO}kdM#U;Tvm_F++^PgfW>!}t0?*NC-lg)8LnN5pz+<c|Sio=H6aLA><`KLn>=;~Of+xm>2&&~g9)@q<>r6DW5p zx1cV%A&yMvXms{JXZZzFyJL_YKlg${v_Zg(*s{APlQEYeS@_)v<`~(g$P42-;5jtN zFbot4@lUYs!RTTVhwm}BT##3Qa8(`HUnm?mu*d36^)Q!yjHVsK8Tvi@{gku=?2Q7K zM*F@VEzDft&f22o01h+0Ss8HK%iLJx-wjq+Q(=%h!nyqR1jsQ+Wt02q!6;hV#aVun z6(yHgEC1wCei>#CQEpYlsDQqSEAb^X{v@fa)%ENwqEs}2 zbIr-q9`-n+*8mMMk_G#4?4WPWwIJWhLVesvAorsD)Yi}& z2PvGv7$b3}ZqX^8B>tUa+u_A+!F}d$o9&7>k^yq7t?Rji7SCJE-Mt2E_24(4cM4kX zMv}@p*4~o>f4Y8!Cxs5CtfTeBWoz^EpNM)&|(um7ztuOlw_81u86_<9(16<<< znm5jB$*A3Au(z>DsGtbaESMbzYA`2gh(S4-;m0*O5sPmOqUwVh1>v{XU|4_(xHM&;-jU?TY}QlOMJ>MTjC%yDeQ<;c?MrGiiIbyG zn+l}CHxy0)#ySFzrCENMf=0gv!0_u{3TGAT%-@b7iLZmOa%#&x4EF;!V<>MKE7U

xK)QW+J%Sel<0`zYY%K% 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 iSXjU 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 XQk6LE&NmlT%>3TPZDrPXoY?;XDS7@B diff --git a/brand/projects/db-retry/mark-512.png b/brand/projects/db-retry/mark-512.png index 57bb47c073502ba2de38f3b08a55d2797b7c17c7..c7dc8eb5b2bce2acbeb82ef2f5d507e4abdee5a9 100644 GIT binary patch literal 4581 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 literal 4602 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 O>Y@EsX2ttx(f + diff --git a/brand/projects/faststream-outbox/lockup-dark.svg b/brand/projects/faststream-outbox/lockup-dark.svg index bf0970b..7f54e4d 100644 --- a/brand/projects/faststream-outbox/lockup-dark.svg +++ b/brand/projects/faststream-outbox/lockup-dark.svg @@ -1 +1 @@ - + diff --git a/brand/projects/faststream-outbox/lockup-light.svg b/brand/projects/faststream-outbox/lockup-light.svg index a5f9ac9..11a94ce 100644 --- a/brand/projects/faststream-outbox/lockup-light.svg +++ b/brand/projects/faststream-outbox/lockup-light.svg @@ -1 +1 @@ - + diff --git a/brand/projects/faststream-outbox/lockup.png b/brand/projects/faststream-outbox/lockup.png index f3543d0fe91bd8752a5516354d9f6aa59681f0ca..caf9e7e86b646b571f8b9d47a98289281523098e 100644 GIT binary patch delta 1981 zcmV;u2SWJj5A6?-DIrQ)S~F&5&zdB;i~vA@K>z;$<;<4Zv03tl0N%WD)f~ifPgb_QV$H`HUIzsAaqhrQw0U~1q1>4{{mXR z0R8@j6M@mKFHUV1(6KHEZch9H4fFNQrT_p397#k$RCwC$o#}$BDhz<_EN8iGp%Bp4 zdi4F@@)9<2tG3nYnR}BTGnUHs0ZD&|IFs#3UMLwM_>TD1ArVC!pTMu!{c`9CaeM-Q zkL3eG90@<+Cn5ZVpM>xeeiFh@_(=%=H^46_=e z_z6D=;V1kgFU6l%#Q1gi^WsE|*TsLmR+rDE^pAvpW&B5!bCoZmPx#lyUmSm(obmzMjqfWKLz_5Vlw#rcZ* z{{3V%%V%*c2JZjqIIDb?S}yb6A77gKHKLh*C4L)o$Q|U$s-J2@{A|=Z8^iH3{N^a; zEAczSTUi5Jm_5LGsQn55ra_0Rb2u;7{i%k|58>a|^m>Q$jFvSYY9D{Xzp>|&PW*X!lWP*hTl+K};1Y?w7ImI1IKZ%$oUvgg@|JD_^jH zxZptenz$T28_zuqsk(FBh`=k~wu5%~eGRP}7W3OGYZ+?bhtc(V2mU;F+bkDnxY%Fz zX_m1BPvGativm2MZ@N$>_*vV;E`H%J1JJe`viAl80t*Ae#bJLe=mDZFqn^hfn;MEq z^6L(DIsO*JBK*I8|MSPoTi8l{T8(eLo(dPjo%ofhRA{X^RxcHNG&qZ;-ws2`v1hu} z+N3hAupa_;fK3IiahhYQC9FZ&b%R5pn!U}bTue`B$UZQW`0y;u{0F>2V5Lg-^f%sN z^4KptiynTX7O{UyZKsXERbt8$0dgn5_Hjk&rj&eC_y7L$L?xp8x6k z{)Fk}ep+PiEv4`UI340mFZk~GRM}1{)&@{z7K3@EO{(Kk0}n@qSgWN`_EZ86M;Xh2 z5&Rv~>)T}4oecT27|w+_?E%-@qxgUPJa(m+GZ2q?J`#VUK>NC@5m-c*b|AqIkxnGZ zdMjPK&pe=PtLXYwNU2Fia~6N-K`CrGCXXoFI&FT`av-N7yG!uDCA0tSc4kUc^aOs@ebv>F$z<>4%Srqp zi%4IQ^$X(`e%T9uj^$5G&R>Zi%@t%u|FCv7mv(Fz^mm(ES_Yhqltdt4UptfMmx5FE)yQ7rafIx9hX8h4@th0H;Nr-pWVttFF=3 zNq&C_w>|CoY>i*G^BrR{!g-iw2R{hsP{R~{yirHJf%~wCpC15Gfx^a%dc z@NkzD95K=6f70*Y6n_(%48A+e$7uXi^7w@h33M(}iw$$y=WBx47zrwC}ThoiROU-{|@O&&SX+J|}+l8rNdq0BT`98u$byV2f zGA-vlpN{r7nOqq$PUlJ$L;QH3kTL<+&%Y$*BRc-tSL2WVq4F$a=qwF7w81RcPvCET zPXTG<)I^6C<8RA|=f5D7IpX<5r&%ZdQj&jB#B&aRu?c?0LdTVH{G?g)=K1+9CJ289 z-G}P6OXVT896oaA8cSl)$^mob0JCXLtWq-;?qEHeSoX@mmYPyb^ZXh)RPz4qKj1S@80RMWYT?zmF z_*Xn@O!)7{zvfAA!hbLRRnOTI{yTs1ultq*;lB_6%I}yE{=4w6{e}e_z6D=;V1lrf9CrteaK!B{x8PgJz{cNCxeeiFh@_z6GZ|BnS75}|*c^YtM&l9vXYNeKUUkbePb*{%`5sT6gD P00000NkvXXu0mjfV-FNo delta 1977 zcmV;q2S)hq59$w)DKN>305fb^N?Kalvs?gxfalVrxr_kw@Z`^$BtU>b|Nj8xiUaTO z?Ce_z6D=;V1kgg#R1h7Zh}OC4NRBw{L-;gzyu762edTNeDmT zCn5ZVpM>xeev+5sKhrU~7vevkj>LFb{6$e*Kj+dv5dMYnA5bpEc@}-bzcl{S!O8JF zgFfM3UiZIUi+>9aK=E^uKH*=-^q!A~?ddv2pYSh@|NNE=z;%NDE&L@YAp8%QUT=5{ zR6w`s-@tEQ7fb$K$?+xJ^hZ4(XLzq;^FPub#}BSX_{R9D{Y!Y=^B|1$2IqIDiC!qisncun{p^L)$-xPSb#`oDMtf4M~K|Bv`jmjd>w9b{S+(WXM@(+7><|WH%BpF zi9Z@%V_;8a4{+&gf5N|N(4lY+rzZEga9+@|p8MK|@UQIoq!a(rV?2$& z0o?I&UVphQn9@qMJhz}Vl(vuDG){5*RcRgqbW|(O4SvAX2LA)CTrs;E3ra_eE0Yik zuDN|$`6uw%vfr{TBw4TpJpE+qHu&+Q!(U@@JnvbX-_#gtXxf6F!GA7Xz`+py+`ZXB zIQG2DY5Z~@H@#d7_c;V0wEI<8*hP2kAf^fx_kYXSdmIK^6lSe_LBbz+uaz%YKwNMj zd`(;qo{i@ohE(}nHzM$pZ`)ow{Jw_P4U740m9-2t@crO=os0k1`}_NE^Y5R7k275D z5BoODtbr%+^W>rcPw1O2GzoszHZjL9{Ko*a?S|~!KtNz&K)Bcs1wBBtWz^I7V^c#h zNq>HwQJ2HFAZFoz|MO?_!^ub3N`2aiZ@r!Z7s8$Rm8n!{tvOaN6>LkK#nNwwq2bsw z-Dqu6nO4{j0VQBlfoq)Rm}&`YP5W)fS^!pwib2Lx8CWJiDF z6DE)S!n5e$H);{9)OOkkTqUMF5g=#zwSSK*N;jqCqq_h1=Hrlyd*y3pe{n?5|5&^| zVS2fr7L~iD6utnbL%it)-yNSS+eyXR0IIBFFt4#mbzExT;iwR6wKSTJO2FZ0Vi_=i zKQq0)O?KVMkiUxIT!_;iaJ@Z<|JSAie>{%!oaZAk3bdweU+2ZW+}%_%A;;o1pv6 zhmXTTme2lY@#nL@{Fma#HCzou5|p3mnQ`0(r*csFbX>dE7V8Q8g8>fNRX+Q^ z?yq~w2YTMY^SXac{Loe!c$KN^5s;KT@M44b%iwL=yt&W9X5v=~0Gt+e`Y0d3uX3ZU zll%}Kd)o6^8^3JlJH}*$^M5d#3_l3xP{SC0d{9Tdf%~wCpYLblZ(5?I^uEs$dHlkMggoQ{{5-fz)<%QK7M>oNST1^=ARSu5t+aC)%c@-s65LUI!l8NZ7>UVBluh2 zQ$QLyHPNBj_}en#`7a1%4tPG%Y1WCql;ock@tnecS_MC2q2tOpe$uRY^ZvYy34%fX zQoVMmJft@LSMFS6Nq;O_Ibg0FU^cCcRcgk<6Rcwsn@$av=Qo;a~WU3E{sB|9;Xpdyf<{P_`+<4idb{x$GFAcUXr z6MhoHPxwg)Kj9}K{DhzI6aN2L&><1}(>Y%sawBbe+T&sf=-Krz~YB^00000 LNkvXXu0mjfQ8ouD diff --git a/brand/projects/faststream-outbox/mark-1024.png b/brand/projects/faststream-outbox/mark-1024.png index 046f5dc5f85d4a4837b7d2a96f68db5931aee499..0a6c3a49e294b187b697029cbc41dcb1ead6ceb3 100644 GIT binary patch literal 7963 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 literal 7898 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 diff --git a/brand/projects/faststream-outbox/mark-512.png b/brand/projects/faststream-outbox/mark-512.png index 07e68750f988bd95d82cb243352cfda5faac6583..68c6c236388e62956f867a7fabe71ef38a6c37e7 100644 GIT binary patch delta 2680 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 literal 3384 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 diff --git a/brand/projects/faststream-outbox/mark.svg b/brand/projects/faststream-outbox/mark.svg index 10d3337..1481550 100644 --- a/brand/projects/faststream-outbox/mark.svg +++ b/brand/projects/faststream-outbox/mark.svg @@ -1 +1 @@ - + diff --git a/brand/projects/faststream-outbox/social-card.png b/brand/projects/faststream-outbox/social-card.png index ed87a5dd303fdd953ead7815ee4e54ec8b8cce97..14145e43ffb16bb412f4dc9fee293a8747da4566 100644 GIT binary patch literal 13946 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

Mqs{t-aJD&A%N9FS!^lk&W%uY*NK(6P^FK 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 + diff --git a/planning/changes/2026-07-12.01-seven-new-project-marks.md b/planning/changes/2026-07-12.01-seven-new-project-marks.md index ca0b54c..1a2200d 100644 --- a/planning/changes/2026-07-12.01-seven-new-project-marks.md +++ b/planning/changes/2026-07-12.01-seven-new-project-marks.md @@ -141,6 +141,10 @@ committed. eye sat in the ring's hollow counter with no gold beneath it; `celery_stalk`'s bands poked past the capsule's curved cap; `plane`'s round-capped crease spilled past the hull at the nose) and were fixed in a follow-up pass, with - `test_new_marks_have_no_cream_on_transparent` added as the regression guard. - The durable lesson: composite every new mark onto a dark background before - it ships, not just a light one. + `test_no_cream_on_transparent` added as the regression guard. Auditing the + guard across the whole manifest then exposed two *pre-existing* marks with the + same defect — `db-retry` and `faststream-outbox`, whose shared `_cyl` helper + stroked its cream rim centred on the top cap's ellipse, putting half the stroke + outside the cylinder's silhouette. `_cyl`'s rim is now inset by half its stroke + width, so the guard covers every mark with no exemptions. The durable lesson: + composite every mark onto a dark background before it ships, not just a light one. diff --git a/tests/test_projects.py b/tests/test_projects.py index 938726f..d618258 100644 --- a/tests/test_projects.py +++ b/tests/test_projects.py @@ -175,31 +175,6 @@ def test_render_projects_writes_cards_for_docs_repos_only(tmp_path: Path) -> Non # every other guard in this file) so a repo added later is covered # automatically instead of needing to be opted in. # -# db-retry and faststream-outbox carry a faint standalone-cream hairline from -# _cyl's 0.8-wide rim stroke straddling an ellipse edge — the same class of bug, -# pre-existing and out of scope for this change. strict=True means the day _cyl -# is fixed, these turn red and force this exclusion to be removed. -KNOWN_CREAM_ON_TRANSPARENT = {"db-retry", "faststream-outbox"} - - -def _cream_guard_params() -> list[object]: - return [ - pytest.param( - repo, - marks=pytest.mark.xfail( - strict=True, - reason=( - "known pre-existing _cyl rim-stroke cream hairline; " - "see KNOWN_CREAM_ON_TRANSPARENT" - ), - ), - ) - if repo in KNOWN_CREAM_ON_TRANSPARENT - else repo - for repo in sorted(EXPECTED_REPOS) - ] - - def _cream_pixels_without_gold_beneath( repo: str, tmp_path: Path, size: int = 256 ) -> list[tuple[int, int]]: @@ -252,8 +227,8 @@ def _cream_pixels_without_gold_beneath( @pytest.mark.skipif( shutil.which("rsvg-convert") is None, reason="rsvg-convert not installed" ) -@pytest.mark.parametrize("repo", _cream_guard_params()) -def test_new_marks_have_no_cream_on_transparent(repo: str, tmp_path: Path) -> None: +@pytest.mark.parametrize("repo", sorted(EXPECTED_REPOS)) +def test_no_cream_on_transparent(repo: str, tmp_path: Path) -> None: bad = _cream_pixels_without_gold_beneath(repo, tmp_path) assert not bad, ( f"{repo}: {len(bad)} cream pixel(s) with no gold beneath, e.g. {bad[:5]} "