From d139c62d77eec51396d22d80150503149f2fe100 Mon Sep 17 00:00:00 2001 From: Artur Shiriev Date: Tue, 30 Jun 2026 18:36:58 +0300 Subject: [PATCH 1/5] docs: design README logos Centered light/dark logo banner atop all 17 repo READMEs, rendering on GitHub ( light/dark SVG) and PyPI (PNG fallback). Assets generated in brand/build (lockup-light/dark.svg + lockup.png) and served centrally from .github by raw URL; READMEs replace their H1 with the banner. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../2026-06-30.04-readme-logos/design.md | 159 ++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 planning/changes/2026-06-30.04-readme-logos/design.md diff --git a/planning/changes/2026-06-30.04-readme-logos/design.md b/planning/changes/2026-06-30.04-readme-logos/design.md new file mode 100644 index 0000000..7203885 --- /dev/null +++ b/planning/changes/2026-06-30.04-readme-logos/design.md @@ -0,0 +1,159 @@ +--- +summary: Add a centered light/dark logo banner to all 17 repo READMEs, served from .github; generate light/dark/png lockups in brand/build. +--- + +# Design: README logos + +## Summary + +Give every org repo (all 17) a centered brand banner at the top of its README: +the project's framed lockup (mark + name), theme-aware on GitHub (light/dark) and +rendering on PyPI. Two parts: **(1)** extend `brand/build` to emit three lockup +assets per repo — `lockup-light.svg`, `lockup-dark.svg`, `lockup.png` — committed +in `.github` under `brand/projects//`; **(2)** a 17-repo rollout that +replaces each README's leading `# ` heading with a `` banner +pointing at those assets via absolute `raw.githubusercontent.com` URLs. + +## Motivation + +The brand kit shipped marks, social cards, and og:image, but the most-seen +surface — each repo's README (which, for every published package, is also the +PyPI `long_description`) — still opens with a bare `# `. A logo banner +completes the rollout and gives the family a consistent first impression on both +GitHub and PyPI. + +## Background: dual-surface rendering (researched) + +- **GitHub** renders absolute `raw.githubusercontent.com/*.svg` URLs (served + `image/svg+xml`) and supports light/dark via `` + + `prefers-color-scheme`. SVGs are sandboxed (no JS/external refs) — fine for + static logos. +- **PyPI** (`readme_renderer`) strips inline `` and ``/`srcset`, so a + `` collapses to its `` fallback, which must be a **PNG at an + absolute https URL** (relative paths don't resolve on PyPI). `

`, + ``, `width`, `alt` are allowed. +- All sampled package repos set `readme = "README.md"`, so the banner must satisfy + both surfaces. The ``+PNG-fallback pattern does. + +## Non-goals + +- The org **profile README** (`profile/README.md`) — it's the org landing page, + not a per-repo banner target. +- A tagline under the logo (decided: replace the H1 with just the centered logo). +- Per-repo committed assets — assets live centrally in `.github` (decided), + referenced by raw URL. No asset files added to the 17 repos. +- Any change to marks, social cards, or og:image. + +## Design + +### 1. Lockup assets in `brand/build` (`.github`) + +`project_lockup` currently produces one light lockup. Generalize it to a colourway +and emit a dark sibling: + +```python +def project_lockup(repo: str, *, dark: bool = False) -> str: + """Framed mark + the repo name in Jost. Light = green-ink/gold on transparent + (for light UIs); dark = cream/gold-dark on transparent (for dark UIs).""" + struct = t.CREAM if dark else t.GREEN_INK + accent = t.GOLD_DARK if dark else t.GOLD_LIGHT + name_color = t.CREAM if dark else t.GREEN_INK + mark_frame = g.project_frame(struct=struct, accent=accent) + inner = MANIFEST[repo]() + if dark: + inner = inner.replace(t.GOLD_LIGHT, t.GOLD_DARK) # inner gold reads on dark; cream negatives stay + name_x = _LOCKUP_H + _GAP + name_svg, name_w = outline_text( + repo, _NAME_SIZE, x=name_x, baseline_y=_LOCKUP_H / 2 + _NAME_SIZE * 0.34, + anchor="start", color=name_color, + ) + total_w = round(name_x + name_w + _GAP) + return ( + f'{mark_frame}{inner}{name_svg}' + ) +``` + +The dark colourway mirrors the org `wordmark-dark` and the on-green mark +colourway. The `inner.replace(GOLD_LIGHT, GOLD_DARK)` recolor is reliable because +the symbols emit exact token hex strings; `CREAM` negative-space stays cream +(visible on dark). (The `pytest` bar-tint literals aren't swapped — they're gold +shades that read fine on dark.) + +`render_projects` writes, per repo, in place of today's single `lockup.svg`: +`lockup-light.svg` (= `project_lockup(repo)`), `lockup-dark.svg` +(= `project_lockup(repo, dark=True)`), and `lockup.png` — the **light** lockup +rasterized via the existing `export_png` (so it's auto-quantized; PyPI bg is +white, so the light lockup is the right fallback). + +### 2. README banner (each of the 17 repos) + +Replace the leading `# ` line with: + +```html +

+ + + + <repo> + +

+``` + +Everything else in each README (the badges row, all content) is unchanged. The +`` placeholders are the repo name; `width="420"` is tunable. + +### 3. Rollout & sequencing + +1. **`.github` PR** — generate + commit the three lockups per repo. Must merge to + `main` **first**, so the `…/main/…` raw URLs resolve. +2. **17 README PRs** — one per repo, README-only (no asset copies), replacing the + H1 with the banner. Independent of each other; open after step 1 merges. + +The 17 repos: modern-di, that-depends, modern-di-fastapi, modern-di-litestar, +modern-di-faststream, modern-di-typer, modern-di-pytest, fastapi-sqlalchemy-template, +litestar-sqlalchemy-template, lite-bootstrap, httpware, faststream-redis-timers, +faststream-concurrent-aiokafka, faststream-outbox, db-retry, eof-fixer, semvertag. +(`fastapi-sqlalchemy-template` uses `readme.md`, lowercase — handle per repo.) + +## Operations + +After step 1 merges, the assets are live at +`https://raw.githubusercontent.com/modern-python/.github/main/brand/projects//lockup-*.{svg,png}`. +Each README PR renders its banner once both that PR and step 1 are on `main`. + +## Out of scope + +- profile README; taglines; per-repo asset hosting; non-README brand assets. + +## Testing + +**`.github` (`brand/build`):** render to a tmp dir and assert, for a sample repo, +that `lockup-light.svg`, `lockup-dark.svg`, `lockup.png` are written; the dark SVG +contains `CREAM`/`GOLD_DARK` and **not** `GREEN_INK`; the light SVG contains +`GREEN_INK`; both parse as XML; `lockup.png` opens mode `"P"` (quantized). Full +`pytest` + `just check-planning` green; `render` clean and deterministic (no PNG +churn). + +**Per repo:** the README's first non-blank line is the `

` +banner; there is no leading `# ` heading; the three `srcset`/`src` URLs name +that repo and the correct asset filenames; the package still builds where +applicable (`uvx twine check` on a built sdist/wheel, or the repo's CI). + +## Risk + +- **Raw-URL availability / path stability.** READMEs depend on the `.github` + `main` raw path. Likelihood low (path is stable; `.github` is canonical), impact + medium (broken image if moved). *Mitigation:* keep `brand/projects//` + paths stable; they're already the established layout. +- **Dark recolor correctness.** The `GOLD_LIGHT→GOLD_DARK` swap + cream name could + in principle misrender a symbol on dark. Likelihood low (verified colourway + matches the marks' on-green treatment), impact low. *Mitigation:* the test + asserts the dark SVG's palette; spot-render one dark lockup during the `.github` + task. +- **PyPI sanitization variance.** If a renderer drops `` AND the ``, + no logo shows. Likelihood low (the ``+`

` are in readme_renderer's + allowlist). *Mitigation:* `twine check` in the per-repo verification. +- **Heading removal churn.** The exact `# ` line varies slightly per repo + (and one uses `readme.md`). *Mitigation:* the rollout reads each README first + and replaces only the leading H1. From 0dce95d4ba924b37aa0c1e7b0c6aae9c2b6eca38 Mon Sep 17 00:00:00 2001 From: Artur Shiriev Date: Tue, 30 Jun 2026 18:39:31 +0300 Subject: [PATCH 2/5] docs: implementation plan for README logos Phase 1 (.github): light/dark/png lockups in brand/build + docs. Phase 2: 17 README PRs replacing the H1 with a centered banner served from .github. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../2026-06-30.04-readme-logos/plan.md | 277 ++++++++++++++++++ 1 file changed, 277 insertions(+) create mode 100644 planning/changes/2026-06-30.04-readme-logos/plan.md diff --git a/planning/changes/2026-06-30.04-readme-logos/plan.md b/planning/changes/2026-06-30.04-readme-logos/plan.md new file mode 100644 index 0000000..65c5f9d --- /dev/null +++ b/planning/changes/2026-06-30.04-readme-logos/plan.md @@ -0,0 +1,277 @@ +# README logos — implementation plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use +> superpowers:subagent-driven-development (recommended) or +> superpowers:executing-plans to implement this plan task-by-task. Steps +> use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** A centered, theme-aware brand banner atop all 17 repo READMEs — +generated as light/dark/PNG lockups in `.github` and embedded via ``. + +**Spec:** [`design.md`](./design.md) + +**Branch (this `.github` bundle + assets):** `brand-readme-logos`. **Per docs/repo branch:** `readme-logo`. + +**Commit strategy:** Tasks 1–2 = the `.github` PR; Tasks 3+ = one PR per repo. + +## Global constraints + +- **Two phases, ordered:** Phase 1 = the `.github` PR (lockup assets + docs; + Tasks 1–2). It must be **merged to `main` first** so the + `raw.githubusercontent.com/.../main/...` URLs resolve. Phase 2 = the 17 + README PRs (Task 3 pilot + Task 4 the rest), opened after Phase 1 is on `main`. +- **Assets are central** in `.github` `brand/projects//`; the 17 repo PRs + are **README-only** (no asset copies). +- **Lockup colourways:** light = `struct=GREEN_INK`, `accent=GOLD_LIGHT`, name + `GREEN_INK`; dark = `struct=CREAM`, `accent=GOLD_DARK`, name `CREAM`, inner gold + `GOLD_LIGHT`→`GOLD_DARK` (cream negatives stay). Tokens: `GREEN_INK #356852`, + `GOLD_LIGHT #c98a00`, `GOLD_DARK #f0b528`, `CREAM #f4f1e8`. +- **Per-repo assets:** `lockup-light.svg`, `lockup-dark.svg`, `lockup.png` (the + light lockup rasterized via `export_png`, hence auto-quantized). +- **The 17 repos:** modern-di, that-depends, modern-di-fastapi, modern-di-litestar, + modern-di-faststream, modern-di-typer, modern-di-pytest, + fastapi-sqlalchemy-template, litestar-sqlalchemy-template, lite-bootstrap, + httpware, faststream-redis-timers, faststream-concurrent-aiokafka, + faststream-outbox, db-retry, eof-fixer, semvertag. +- **The README banner** (exact; substitute `` — its README filename is + `README.md` except `fastapi-sqlalchemy-template`, which uses `readme.md`): + + ```html +

+ + + + <repo> + +

+ ``` + +- **Per-repo README procedure** (Task 3 and each repo in Task 4): + 1. `gh repo clone modern-python/ /Users/kevinsmith/src/pypi/.readme-clones/` (mkdir the parent once; `git -C … pull --ff-only` if it exists). + 2. `cd` in; `git checkout -b readme-logo`. + 3. In the README (`README.md`, or `readme.md` for the template), **replace the + leading H1** — the first line matching `^# \s*$` — with the banner + block above (repo substituted). If there is no leading `# ` line, + insert the banner as the first line instead (and report it). Leave the badge + row and all other content untouched. + 4. Verify (below). + 5. `git add -A && git commit -m "docs: add brand logo banner to README"`; + `git push -u origin readme-logo`; `gh pr create --base main` (body: one line + + the 🤖 line). + 6. `gh pr checks ` to completion. + +- **Per-repo verification:** (a) the README's first non-blank line is + `

` and the file no longer contains a leading `# ` + heading; (b) all three URLs contain `/brand/projects//` and the filenames + `lockup-dark.svg` / `lockup-light.svg` / `lockup.png`; (c) if the repo builds a + distribution, `uv build` then `uvx twine check dist/*` reports PASS (this + validates the long_description renders for PyPI); if it isn't a package (the two + templates), skip twine and just confirm (a)+(b). +- Imports at module level; annotate args; `# ty: ignore` not `# type: ignore`. + CI gate is `just` (= check-planning + pytest); ruff not a gate. + +--- + +### Task 1: Light/dark/PNG lockups in `brand/build` + +**Files:** +- Modify: `brand/build/projects.py` +- Test: `tests/test_lockups.py` (new) +- Regenerate: `brand/projects/**/lockup-*.svg`, `brand/projects/**/lockup.png` + +**Interfaces:** +- Produces: `project_lockup(repo: str, *, dark: bool = False) -> str`; + `render_projects` writes `lockup-light.svg`, `lockup-dark.svg`, `lockup.png` per + repo (replacing the old single `lockup.svg`). + +- [ ] **Step 1: Write the failing test** + + ```python + # tests/test_lockups.py + from pathlib import Path + from xml.dom import minidom + + from PIL import Image + + from brand.build import projects as p + from brand.build import tokens as t + + + def test_light_and_dark_lockup_colourways() -> None: + light = p.project_lockup("modern-di") + dark = p.project_lockup("modern-di", dark=True) + minidom.parseString(light) + minidom.parseString(dark) + assert t.GREEN_INK in light and t.GOLD_LIGHT in light + # dark uses the on-dark colourway: cream + gold-dark, never the dark-green ink + assert t.CREAM in dark and t.GOLD_DARK in dark + assert t.GREEN_INK not in dark + + + def test_render_writes_three_lockup_assets(tmp_path: Path) -> None: + p.render_projects(out_dir=tmp_path) + d = tmp_path / "modern-di" + assert (d / "lockup-light.svg").is_file() + assert (d / "lockup-dark.svg").is_file() + png = d / "lockup.png" + assert png.is_file() + assert Image.open(png).mode == "P" # quantized via export_png + ``` + +- [ ] **Step 2: Run to verify it fails** + + Run: `uv run pytest tests/test_lockups.py -q` + Expected: FAIL — `project_lockup` has no `dark` kwarg / `lockup-light.svg` not written. + +- [ ] **Step 3: Generalize `project_lockup` + emit three assets** + + Replace `project_lockup` in `brand/build/projects.py` with: + + ```python + def project_lockup(repo: str, *, dark: bool = False) -> str: + """Framed mark + the repo name in Jost. Light = green-ink/gold (light UIs); + dark = cream/gold-dark (dark UIs). Transparent background either way.""" + struct = t.CREAM if dark else t.GREEN_INK + accent = t.GOLD_DARK if dark else t.GOLD_LIGHT + name_color = t.CREAM if dark else t.GREEN_INK + mark_frame = g.project_frame(struct=struct, accent=accent) + inner = MANIFEST[repo]() + if dark: + inner = inner.replace(t.GOLD_LIGHT, t.GOLD_DARK) + name_x = _LOCKUP_H + _GAP + name_svg, name_w = outline_text( + repo, + _NAME_SIZE, + x=name_x, + baseline_y=_LOCKUP_H / 2 + _NAME_SIZE * 0.34, + anchor="start", + color=name_color, + ) + total_w = round(name_x + name_w + _GAP) + return ( + f'{mark_frame}{inner}{name_svg}' + ) + ``` + + In `render_projects`, replace the single `lockup.svg` write line with: + + ```python + (d / "lockup-light.svg").write_text(project_lockup(repo) + "\n", encoding="utf-8") + dark_svg = d / "lockup-dark.svg" + dark_svg.write_text(project_lockup(repo, dark=True) + "\n", encoding="utf-8") + export_png(d / "lockup-light.svg", d / "lockup.png") + ``` + + (`export_png(svg, png)` with no width/height rasterizes at the SVG's natural size + and quantizes; that's the light PNG fallback.) Update the `render_projects` + docstring's "lockup.svg" mention to the three new names. + +- [ ] **Step 4: Run to verify it passes** + + Run: `uv run pytest tests/test_lockups.py -q` + Expected: PASS (2 tests). + +- [ ] **Step 5: Regenerate + sanity-render a dark lockup, then commit** + + ```bash + uv run python -m brand.build.render + rsvg-convert -w 480 brand/projects/modern-di/lockup-dark.svg -o /tmp/lockup-dark.png # eyeball: cream+gold-dark on transparent + git add brand/build/projects.py tests/test_lockups.py brand/projects + git status --short | grep -E "lockup\.svg" && echo "NOTE: old lockup.svg files are now untracked/removed — git rm them" || true + git rm brand/projects/*/lockup.svg 2>/dev/null || true + git add brand/projects + git commit -m "feat(brand): light/dark/png lockups for README banners" + ``` + The `git rm` removes the superseded single `lockup.svg` per repo (render no + longer writes it). Confirm `git status` is clean after. + +--- + +### Task 2: `.github` docs + finalize bundle + +**Files:** +- Modify: `brand/README.md`, `architecture/brand-marks.md` +- Modify: `planning/changes/2026-06-30.04-readme-logos/design.md` (summary) + +- [ ] **Step 1: `brand/README.md`** — note the lockup outputs changed to + `lockup-light.svg` / `lockup-dark.svg` / `lockup.png` (light + dark colourways + + PyPI PNG fallback), used as README banners across the org. + +- [ ] **Step 2: `architecture/brand-marks.md`** — append: each repo has + `lockup-{light,dark}.svg` + `lockup.png`; the dark colourway is cream + gold-dark + (mirrors `wordmark-dark`); READMEs embed them via `` from the `.github` + raw path. + +- [ ] **Step 3: Finalize the bundle summary** in `design.md`, e.g.: + `summary: README logos shipped — light/dark/png lockups generated in .github; centered banner replaces the H1 in all 17 repo READMEs.` + +- [ ] **Step 4: Verify + commit** + + ```bash + uv run pytest -q # all green + just check-planning # planning: OK + uv run python -m brand.build.render # clean; git status shows no asset churn + git add brand/README.md architecture/brand-marks.md planning/changes/2026-06-30.04-readme-logos/design.md + git commit -m "docs(brand): document README lockups" + ``` + Then push `brand-readme-logos` and open the `.github` PR (Tasks 1–2). **This PR + must merge before Phase 2.** + +--- + +### Task 3: README banner — pilot (`modern-di`) + +> Phase 2. Do this only after the Task 1–2 `.github` PR is merged to `main` +> (otherwise the raw URLs 404). Pilot to confirm the H1 replacement + render. + +**Repo:** `modern-python/modern-di` (`README.md`, leading line `# modern-di`). + +- [ ] **Step 1: Clone + branch** — per the Global per-repo procedure, into `…/.readme-clones/modern-di`, branch `readme-logo`. +- [ ] **Step 2: Replace the leading H1** — swap the first `# modern-di` line for the banner block (Global Constraints), ``=`modern-di`. Confirm the badge row immediately below is untouched. +- [ ] **Step 3: Verify** — first non-blank line is `

`; no `# modern-di` heading remains; the 3 URLs contain `/brand/projects/modern-di/`; `uv build` then `uvx twine check dist/*` → PASS. +- [ ] **Step 4: Commit + push + PR** — `docs: add brand logo banner to README`; `gh pr create --base main`, body names the banner + 🤖 line. +- [ ] **Step 5: Watch CI** — `gh pr checks ` to completion. + +--- + +### Task 4: README banner — remaining 16 repos + +> Phase 2, after the `.github` PR is merged. Apply the **Global per-repo +> procedure** to each repo below; each is its own `readme-logo` branch + PR + +> verification (treat each as an independent unit). README filename is `README.md` +> except `fastapi-sqlalchemy-template` (`readme.md`). For each, verify the 3 URLs +> contain `/brand/projects//`, the leading `# ` H1 is replaced, and +> (packages only) `uvx twine check dist/*` passes after `uv build`. + +- [ ] `that-depends` +- [ ] `modern-di-fastapi` +- [ ] `modern-di-litestar` +- [ ] `modern-di-faststream` +- [ ] `modern-di-typer` +- [ ] `modern-di-pytest` +- [ ] `fastapi-sqlalchemy-template` *(readme.md; not a PyPI package — skip twine, confirm URLs + banner placement; its leading heading may differ, replace the first H1 or insert at top and report)* +- [ ] `litestar-sqlalchemy-template` *(not a PyPI package — skip twine)* +- [ ] `lite-bootstrap` +- [ ] `httpware` +- [ ] `faststream-redis-timers` +- [ ] `faststream-concurrent-aiokafka` +- [ ] `faststream-outbox` +- [ ] `db-retry` +- [ ] `eof-fixer` +- [ ] `semvertag` + +--- + +## Notes for the executor + +- **Hard gate:** open no Phase-2 README PR until the Task 1–2 `.github` PR is on + `main` — the banner URLs resolve only then. +- The 17 README edits are independent and mechanically identical (replace the + leading H1 with the banner, substitute ``); they can be dispatched in + parallel, each its own PR and review. +- Work in `/Users/kevinsmith/src/pypi/.readme-clones/`, never in `.github`. +- Do not touch anything but the leading H1 in each README. +- Some packages may need build deps for `uv build`; if a repo can't build a dist, + fall back to confirming the banner block + URLs and rely on the repo's CI / + `twine check` in its release flow — and say so in the report. From d8d88559e47eef55481fbddc6a7bd5170ba108a6 Mon Sep 17 00:00:00 2001 From: Artur Shiriev Date: Tue, 30 Jun 2026 18:46:07 +0300 Subject: [PATCH 3/5] feat(brand): light/dark/png lockups for README banners --- brand/build/projects.py | 26 ++++++++++------ brand/projects/db-retry/lockup-dark.svg | 1 + .../db-retry/{lockup.svg => lockup-light.svg} | 0 brand/projects/db-retry/lockup.png | Bin 0 -> 1531 bytes brand/projects/eof-fixer/lockup-dark.svg | 1 + .../{lockup.svg => lockup-light.svg} | 0 brand/projects/eof-fixer/lockup.png | Bin 0 -> 1236 bytes .../lockup-dark.svg | 1 + .../{lockup.svg => lockup-light.svg} | 0 .../fastapi-sqlalchemy-template/lockup.png | Bin 0 -> 2713 bytes .../lockup-dark.svg | 1 + .../{lockup.svg => lockup-light.svg} | 0 .../faststream-concurrent-aiokafka/lockup.png | Bin 0 -> 2625 bytes .../faststream-outbox/lockup-dark.svg | 1 + .../{lockup.svg => lockup-light.svg} | 0 brand/projects/faststream-outbox/lockup.png | Bin 0 -> 2026 bytes .../faststream-redis-timers/lockup-dark.svg | 1 + .../{lockup.svg => lockup-light.svg} | 0 .../faststream-redis-timers/lockup.png | Bin 0 -> 2498 bytes brand/projects/httpware/lockup-dark.svg | 1 + .../httpware/{lockup.svg => lockup-light.svg} | 0 brand/projects/httpware/lockup.png | Bin 0 -> 1274 bytes brand/projects/lite-bootstrap/lockup-dark.svg | 1 + .../{lockup.svg => lockup-light.svg} | 0 brand/projects/lite-bootstrap/lockup.png | Bin 0 -> 1689 bytes .../lockup-dark.svg | 1 + .../{lockup.svg => lockup-light.svg} | 0 .../litestar-sqlalchemy-template/lockup.png | Bin 0 -> 2499 bytes .../modern-di-fastapi/lockup-dark.svg | 1 + .../{lockup.svg => lockup-light.svg} | 0 brand/projects/modern-di-fastapi/lockup.png | Bin 0 -> 2093 bytes .../modern-di-faststream/lockup-dark.svg | 1 + .../{lockup.svg => lockup-light.svg} | 0 .../projects/modern-di-faststream/lockup.png | Bin 0 -> 2204 bytes .../modern-di-litestar/lockup-dark.svg | 1 + .../{lockup.svg => lockup-light.svg} | 0 brand/projects/modern-di-litestar/lockup.png | Bin 0 -> 2051 bytes .../projects/modern-di-pytest/lockup-dark.svg | 1 + .../{lockup.svg => lockup-light.svg} | 0 brand/projects/modern-di-pytest/lockup.png | Bin 0 -> 1749 bytes .../projects/modern-di-typer/lockup-dark.svg | 1 + .../{lockup.svg => lockup-light.svg} | 0 brand/projects/modern-di-typer/lockup.png | Bin 0 -> 1705 bytes brand/projects/modern-di/lockup-dark.svg | 1 + .../{lockup.svg => lockup-light.svg} | 0 brand/projects/modern-di/lockup.png | Bin 0 -> 1445 bytes brand/projects/semvertag/lockup-dark.svg | 1 + .../{lockup.svg => lockup-light.svg} | 0 brand/projects/semvertag/lockup.png | Bin 0 -> 1356 bytes brand/projects/that-depends/lockup-dark.svg | 1 + .../{lockup.svg => lockup-light.svg} | 0 brand/projects/that-depends/lockup.png | Bin 0 -> 1648 bytes tests/test_lockups.py | 28 ++++++++++++++++++ 53 files changed, 62 insertions(+), 9 deletions(-) create mode 100644 brand/projects/db-retry/lockup-dark.svg rename brand/projects/db-retry/{lockup.svg => lockup-light.svg} (100%) create mode 100644 brand/projects/db-retry/lockup.png create mode 100644 brand/projects/eof-fixer/lockup-dark.svg rename brand/projects/eof-fixer/{lockup.svg => lockup-light.svg} (100%) create mode 100644 brand/projects/eof-fixer/lockup.png create mode 100644 brand/projects/fastapi-sqlalchemy-template/lockup-dark.svg rename brand/projects/fastapi-sqlalchemy-template/{lockup.svg => lockup-light.svg} (100%) create mode 100644 brand/projects/fastapi-sqlalchemy-template/lockup.png create mode 100644 brand/projects/faststream-concurrent-aiokafka/lockup-dark.svg rename brand/projects/faststream-concurrent-aiokafka/{lockup.svg => lockup-light.svg} (100%) create mode 100644 brand/projects/faststream-concurrent-aiokafka/lockup.png create mode 100644 brand/projects/faststream-outbox/lockup-dark.svg rename brand/projects/faststream-outbox/{lockup.svg => lockup-light.svg} (100%) create mode 100644 brand/projects/faststream-outbox/lockup.png create mode 100644 brand/projects/faststream-redis-timers/lockup-dark.svg rename brand/projects/faststream-redis-timers/{lockup.svg => lockup-light.svg} (100%) create mode 100644 brand/projects/faststream-redis-timers/lockup.png create mode 100644 brand/projects/httpware/lockup-dark.svg rename brand/projects/httpware/{lockup.svg => lockup-light.svg} (100%) create mode 100644 brand/projects/httpware/lockup.png create mode 100644 brand/projects/lite-bootstrap/lockup-dark.svg rename brand/projects/lite-bootstrap/{lockup.svg => lockup-light.svg} (100%) create mode 100644 brand/projects/lite-bootstrap/lockup.png create mode 100644 brand/projects/litestar-sqlalchemy-template/lockup-dark.svg rename brand/projects/litestar-sqlalchemy-template/{lockup.svg => lockup-light.svg} (100%) create mode 100644 brand/projects/litestar-sqlalchemy-template/lockup.png create mode 100644 brand/projects/modern-di-fastapi/lockup-dark.svg rename brand/projects/modern-di-fastapi/{lockup.svg => lockup-light.svg} (100%) create mode 100644 brand/projects/modern-di-fastapi/lockup.png create mode 100644 brand/projects/modern-di-faststream/lockup-dark.svg rename brand/projects/modern-di-faststream/{lockup.svg => lockup-light.svg} (100%) create mode 100644 brand/projects/modern-di-faststream/lockup.png create mode 100644 brand/projects/modern-di-litestar/lockup-dark.svg rename brand/projects/modern-di-litestar/{lockup.svg => lockup-light.svg} (100%) create mode 100644 brand/projects/modern-di-litestar/lockup.png create mode 100644 brand/projects/modern-di-pytest/lockup-dark.svg rename brand/projects/modern-di-pytest/{lockup.svg => lockup-light.svg} (100%) create mode 100644 brand/projects/modern-di-pytest/lockup.png create mode 100644 brand/projects/modern-di-typer/lockup-dark.svg rename brand/projects/modern-di-typer/{lockup.svg => lockup-light.svg} (100%) create mode 100644 brand/projects/modern-di-typer/lockup.png create mode 100644 brand/projects/modern-di/lockup-dark.svg rename brand/projects/modern-di/{lockup.svg => lockup-light.svg} (100%) create mode 100644 brand/projects/modern-di/lockup.png create mode 100644 brand/projects/semvertag/lockup-dark.svg rename brand/projects/semvertag/{lockup.svg => lockup-light.svg} (100%) create mode 100644 brand/projects/semvertag/lockup.png create mode 100644 brand/projects/that-depends/lockup-dark.svg rename brand/projects/that-depends/{lockup.svg => lockup-light.svg} (100%) create mode 100644 brand/projects/that-depends/lockup.png create mode 100644 tests/test_lockups.py diff --git a/brand/build/projects.py b/brand/build/projects.py index 2be4955..f01310c 100644 --- a/brand/build/projects.py +++ b/brand/build/projects.py @@ -58,10 +58,16 @@ def project_mark(repo: str) -> str: ) -def project_lockup(repo: str) -> str: - """Framed mark on the left + the repo name in Jost (green) to its right.""" - mark_frame = g.project_frame(struct=t.GREEN_INK, accent=t.GOLD_LIGHT) +def project_lockup(repo: str, *, dark: bool = False) -> str: + """Framed mark + the repo name in Jost. Light = green-ink/gold (light UIs); + dark = cream/gold-dark (dark UIs). Transparent background either way.""" + struct = t.CREAM if dark else t.GREEN_INK + accent = t.GOLD_DARK if dark else t.GOLD_LIGHT + name_color = t.CREAM if dark else t.GREEN_INK + mark_frame = g.project_frame(struct=struct, accent=accent) inner = MANIFEST[repo]() + if dark: + inner = inner.replace(t.GOLD_LIGHT, t.GOLD_DARK) name_x = _LOCKUP_H + _GAP name_svg, name_w = outline_text( repo, @@ -69,19 +75,18 @@ def project_lockup(repo: str) -> str: x=name_x, baseline_y=_LOCKUP_H / 2 + _NAME_SIZE * 0.34, anchor="start", - color=t.GREEN_INK, + color=name_color, ) total_w = round(name_x + name_w + _GAP) return ( f'' - f"{mark_frame}{inner}" - f"{name_svg}" + f'role="img" aria-label="{repo}">{mark_frame}{inner}{name_svg}' ) def render_projects(out_dir: Path | None = None) -> list[Path]: - """Write mark.svg, lockup.svg (+ PNGs) for every repo under out_dir//. + """Write mark.svg, lockup-light.svg, lockup-dark.svg, lockup.png (+ mark PNGs) + for every repo under out_dir//. Docs-site repos (DOCS_REPOS) also get social-card.svg/png (1280×640).""" base = out_dir if out_dir is not None else PROJECTS @@ -93,7 +98,10 @@ def render_projects(out_dir: Path | None = None) -> list[Path]: svg.write_text(project_mark(repo) + "\n", encoding="utf-8") for sz in _PNG_SIZES: export_png(svg, d / f"mark-{sz}.png", width=sz, height=sz) - (d / "lockup.svg").write_text(project_lockup(repo) + "\n", encoding="utf-8") + (d / "lockup-light.svg").write_text(project_lockup(repo) + "\n", encoding="utf-8") + dark_svg = d / "lockup-dark.svg" + dark_svg.write_text(project_lockup(repo, dark=True) + "\n", encoding="utf-8") + export_png(d / "lockup-light.svg", d / "lockup.png") if repo in DOCS_REPOS: card = d / "social-card.svg" card.write_text( diff --git a/brand/projects/db-retry/lockup-dark.svg b/brand/projects/db-retry/lockup-dark.svg new file mode 100644 index 0000000..be22819 --- /dev/null +++ b/brand/projects/db-retry/lockup-dark.svg @@ -0,0 +1 @@ + diff --git a/brand/projects/db-retry/lockup.svg b/brand/projects/db-retry/lockup-light.svg similarity index 100% rename from brand/projects/db-retry/lockup.svg rename to brand/projects/db-retry/lockup-light.svg diff --git a/brand/projects/db-retry/lockup.png b/brand/projects/db-retry/lockup.png new file mode 100644 index 0000000000000000000000000000000000000000..9b04bac56a09aca32a0192da4b5a90f68a8cac75 GIT binary patch literal 1531 zcmVbXHv+C z05xb*HE2;aXi~_D05oV$HE2;aXi>?E0Lq8}$cX^RiU7%q05xz^wTam|0000WbW%=J z`UVF77~lf}0R#yCt$6_c{)2%s&2G^WO|nlEF>S94lsnss000FlNkleln|9e6WGy;tm!I;$hs zsu}8?Vv8(f;=|Q4_I~%&i?F%bghb~v*#@>5ef%ZuuGdlOePXwUs<301%NJxDsdtGj zIvcLzfl7qT+z$0S#BO^}UBvUTCg9}vjV*@EY$h3dE2ru%vj5Y_X`ZuxiCxU5BTg1q z{3145zfUlSUHe9Q{PUlY?>|T1r0a*luG}2#_?>*c8kX0uV{4})F0HhxT!*B<6Iv9SG)i?JzU4Efj>)%fA{yij^b5n;3^Wklbp9ztdHHK+2* z2c?&ksz*{vPhC&hNLOLM_@mCgl0m*QpYm-jHZ{MCnS)KbfgGH^vMb`MU9%Ew?$ow{ zyP;pS*7fb`dhgpw&=h8{YkzrV^ejbx@I!aK5__zW6AOD73#J~n#>1a-y7)NUlZS1- zAjyimJ8?Hvi?N08shmx<%=dj_9X8VHLWpra*se)_${9jxMEK%jpNZ^?x+##>PL*P% zzL}aTP6*YHaf)SPWa`Fs@DAn4G$0 zp)$QIInAwbO2>D53^pY4ZqsQ*3Sz6dq|vN(#ZqM0A=di}BE4%VVkb|`a%m_HrWw{O zVM~MT6vrky3qb#1;hDZvO(CTbFX^2NPkMHo)PT)D#zBXTgV-S)qbN4*+`_iD8FY?y z7?RY%TWJuTuA?xv!pW)KDU7YL*nOKyv3ifPfEzcJbY{)DG(%`(luASd$1{=HaAhd-T(Q^^mLR^Ab(tfdGFAK$gH#~6muj7wAVO46IK#cWYi zs5d&;W!ZY05{@yKZi(b(*lH`#G!ifF$UjW9S`MlY&e_4;LUgwh={Xj?rbg~Nz9L-w zGX70fuT3GKP1Ad}5PwASxjh#b8->tf`Ywh#(PUmWfPI-$wu_BoMUN1-$l|5_4PcXa z^zyJ#8b8a>ya$V4kplMyu;ZzUhmB^!^7MF4J43wzY!+E)Pq5K!I->kmRfi6=H0c(x z`TSq74A?UkAcX%{`=Uy;awXUDABtAhz5b|6EWWKvy1P6y5}| zg6iHv++I)>LDxH~16g8f;^7MRF0ct&)U_Uhm}r`!ZObxxB5xPiw@Y1%N}jxaHtd)H zHedrbU;{Q_12$j-_RnHhSJqk&itQG6i-l4?7WNGS*nkb#fDPDy4cLGU*qcdCEvcSp hDU!m!We4o-$X_|%bVb~4R1W|E002ovPDHLkV1nR~=yd=9 literal 0 HcmV?d00001 diff --git a/brand/projects/eof-fixer/lockup-dark.svg b/brand/projects/eof-fixer/lockup-dark.svg new file mode 100644 index 0000000..34e29da --- /dev/null +++ b/brand/projects/eof-fixer/lockup-dark.svg @@ -0,0 +1 @@ + diff --git a/brand/projects/eof-fixer/lockup.svg b/brand/projects/eof-fixer/lockup-light.svg similarity index 100% rename from brand/projects/eof-fixer/lockup.svg rename to brand/projects/eof-fixer/lockup-light.svg diff --git a/brand/projects/eof-fixer/lockup.png b/brand/projects/eof-fixer/lockup.png new file mode 100644 index 0000000000000000000000000000000000000000..008209ba38b8dc8ee62fb405ca4119783bba241e GIT binary patch literal 1236 zcmeAS@N?(olHy`uVBq!ia0vp^zkxV~gBeJc&)LQVq!I#rLR^8gX-43QE(X)|pc9=8 zCh0*SZa0HTMi5ZMG{YY#Ws(k307Uy67%U1xPPQ}XL_`>;r7<)#oa|z7NJv<$fDy=1C<*clX88B7xlQMSVUD-(=?zPLxHu&_Seeo}n3))v zSwI?goVA?Kz`(-n>EaktaqI2un@Ot`1loKBTR3MO(eb_gz5YCNSBKR06P_yPVoD^X z=k%xkh?H{8$hhqLMn;&ic*4(Z*%3S5=uS}Qxj9i5fx?fSGh35+^4c|{^Bd~B6s9&b>bHqX!HPyhEHr@iOfZ#l3ls{H?!m8{B*Y7o!c}mtCiW(-id%iJbaI$|0e;p~huqbBH3!Z}D zF7XE$^PZl{*YcQNX!b7tZP@#TualNv+9PZ=FIicy`be%^cI0xFc|jK9k+!W~Z#!4@ z-1#=eiRTmRoA1uY-*w-ZD_oQHeC;bPmbu5`l*6Y!n8MgLcWcSV-^FvMy=s}~xZTt` zEYaIhGo8&tga7dy=h~Myt$23-)0_J;Zu-Ge^>nq+7uP*P)gpuErH59(syppFW$AOZ z-g(j|N=2)0KDc6He1nZG*iJU`=bq-hVau%&!kj{qKb`Sv(R?E{Y1aPhXV1M>be;7+ zlGnPh&G54CVvF+WDaKpvrE%9zo|`rON(*OA42OH1GK+iaY_YuCFiYwqq$zQDEV zpxx@bcZ2fh-LUO1zd5h)pzQ4}7oVs1e!rhFjjN7*_vDF-gN_(2H}m*eQZ#RU)}^xx zOyaezuY6wDHE;UXgL$RFhm1e(-mo`*=Zpx=-F2BOW45v=rv>TT9MJx0+qie>>m^}@ zR<0d$ubSE2d>?nCc<#%YQ;xFz+4+j=R`7AdbN8-&o@;dM#@wH6y_?iCAEm#4q>t!;3TD+%1*a@QgLR{!QeXvV_Y!Hl^JBHCM>A*pqLa`>uJ$if6TNCCE+@h^l$| z)xLaMf6JAnU3>m^UbORXzj=Atj-CIW*Uo-1HGLw#_)fmxq4|5Rhx2dZPpaRuFTdw| z^|z^ea@K!pePbIfz1H}}WlbsDX1>0?`PT0{ce5|t_FCo77OuVikFnO(_TU;-p+}%%!PC{xWt~$(698vCMdbhh literal 0 HcmV?d00001 diff --git a/brand/projects/fastapi-sqlalchemy-template/lockup-dark.svg b/brand/projects/fastapi-sqlalchemy-template/lockup-dark.svg new file mode 100644 index 0000000..54ccea1 --- /dev/null +++ b/brand/projects/fastapi-sqlalchemy-template/lockup-dark.svg @@ -0,0 +1 @@ + diff --git a/brand/projects/fastapi-sqlalchemy-template/lockup.svg b/brand/projects/fastapi-sqlalchemy-template/lockup-light.svg similarity index 100% rename from brand/projects/fastapi-sqlalchemy-template/lockup.svg rename to brand/projects/fastapi-sqlalchemy-template/lockup-light.svg diff --git a/brand/projects/fastapi-sqlalchemy-template/lockup.png b/brand/projects/fastapi-sqlalchemy-template/lockup.png new file mode 100644 index 0000000000000000000000000000000000000000..81039186084a1f916bf88a018ec42f1675203a16 GIT binary patch literal 2713 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 literal 0 HcmV?d00001 diff --git a/brand/projects/faststream-concurrent-aiokafka/lockup-dark.svg b/brand/projects/faststream-concurrent-aiokafka/lockup-dark.svg new file mode 100644 index 0000000..4904027 --- /dev/null +++ b/brand/projects/faststream-concurrent-aiokafka/lockup-dark.svg @@ -0,0 +1 @@ + diff --git a/brand/projects/faststream-concurrent-aiokafka/lockup.svg b/brand/projects/faststream-concurrent-aiokafka/lockup-light.svg similarity index 100% rename from brand/projects/faststream-concurrent-aiokafka/lockup.svg rename to brand/projects/faststream-concurrent-aiokafka/lockup-light.svg diff --git a/brand/projects/faststream-concurrent-aiokafka/lockup.png b/brand/projects/faststream-concurrent-aiokafka/lockup.png new file mode 100644 index 0000000000000000000000000000000000000000..fbc590b7a63c4377647c27c510c14343a41e5074 GIT binary patch literal 2625 zcmY*bc{tQ-8y;DXWr%E%VhqZj8A?Kyv5%dQMEscS`%;!eWf|Md;9#1gPWF8aMG~@) zj3|xlLY7EqPKL(v%{k|~zVCeR^*-;jT=(-l*ZtRfqiw8Ac)7*7K_C#XnJK~!1Udm@ z#sDWP^R2m|P|0*2Hb@5}rq{S*OHK!ApzPpxY?v|gs-tYx@7QUeY{_WQU^=KT6~qK6 zIXmllcnqRJdWm}KA$E?Aj-bRuxR1|2nBzoHbv39nkvZ@GPB?kIgjtY^u(PrU9Ui3# zy;H3Vv`VZJwB_U+WdpOGVE4Otf|c{{9^oVRcOVc~h#5lPA!cgx_esx1O@1R@g}^Vp ze6H`|$Hz}g;+w!J*dVzX#;9fH_g8-&)ZQ!%2^s|1BwS_nIxo+c)dUNpNS`uQ%yJNa4_VaFY+ ztl?2t?LWs}8(ZwrGs*lZT9Ly$o01t)IvU~*P$J$@2X+r>0cb_+H=ECu~a zeRl-SdmPtaqHOALn8yW-QRtZcymj+X z$^=m18xYu66jSo2h!DfR48KaL{s=$` zd%G2_0n?7lz2avkdj^*Ye)T&fecs{(tWv@F@<1D zTz)%@GpkbxXA7V?RU_n1LBp(CHy~pcrXQiSosAsiXuaTgTV|%u?pw$7fFJLX1+lR; zZ}>$-pf2H6w({Y>$%|4~7G(nL+2v!2lQr4gvd=aMXHU0F-n7~rc%rDb86eleqYs9U za1s)y&7TM4hc2uLLIO5w<+GdP%9CrH&YenqBU*e)t^A_XBWDA-=CCk$p^egqezvTj zoZ^@bnoUuIKfcBY?O9n{R}R!X1o!0+O{idyY+dht)?ph0^l@9txrqzHI5Vzjxu<+w zR4O?x=%a5`ObB(ipj-Un{^iO()ran9oITxzotAc;R^$k}L-M?@T+b*wF;x_%0MvNb@;ni4T_L@h=1_*We{*U4YK#J7}gu8eCCKKe`WTSmvnL{#1hP<6^Z*IBN2>PVKjHL z!(zACLxd>}tIJVE%g-l@5pbY#B89Cl@_Y<3QxjwTj2770D~Zoy)-gen}{VO%l9I=0X90k z*4dz3B6xW*ziQx_3mPmutv9^hU>)%qMXr=Ke}kaCn7#s}^AD3ZcgW&^pKFkyn7>7+n&gwjLK?yR01hP?cPcls&C1S3e4IMloMqx6!r z`@Pj6)1Api3LmUFMsn<;+9b?#&0r6O6|*axD$i5&!B;(Ze7n%yYkwgF)7s)E*m6_* z?7*K`v*@o%3rjlWFP=N;gKO+B1oFQH+a`bi>eyjMB8Z4>!9#yd7qSkKvH#vUkoTF7 zlj4I7PKUSuwI|`=Mc$yJx7x^l^5Dn*_`sk%Rmjqa9Jj0R73ZMVW4Yb@{cg7cp(TPW zaMM6?r%F&oJD2p?adz*;o(5UQ-T9ZH@{-rzUrR~0p>MO`zoJt0e6*=v{w@Ka%rOH=oPsPP+pm98=x2i#Qy*7Vnw_RzFC4vU53lX82kIJ8a~BW?`qq zPVsVzcYqP-U@o;|Z z{yuqT-_1^MWdIt!)q-KcOR7ZD>D0fp%ip@?ABpnsR7#3QsZId4IektCCqiD6WZ3li+2RRDtg|~PD^3_Z;x7?qW@Lq^H}JUs E9~qC)bpQYW literal 0 HcmV?d00001 diff --git a/brand/projects/faststream-outbox/lockup-dark.svg b/brand/projects/faststream-outbox/lockup-dark.svg new file mode 100644 index 0000000..bf0970b --- /dev/null +++ b/brand/projects/faststream-outbox/lockup-dark.svg @@ -0,0 +1 @@ + diff --git a/brand/projects/faststream-outbox/lockup.svg b/brand/projects/faststream-outbox/lockup-light.svg similarity index 100% rename from brand/projects/faststream-outbox/lockup.svg rename to brand/projects/faststream-outbox/lockup-light.svg diff --git a/brand/projects/faststream-outbox/lockup.png b/brand/projects/faststream-outbox/lockup.png new file mode 100644 index 0000000000000000000000000000000000000000..f3543d0fe91bd8752a5516354d9f6aa59681f0ca GIT binary patch literal 2026 zcmV?D z05xY)GiOlAi2yZcQ8Z^!HE2>bXHhh0Qpkz`%ZLEUiU2HFSjdV12fXo60000WbW%=J zUJ3>M0`~=9{saLK8JX5r0R8@j6M@mKFHUXH7qJK~^)fMj000LWNklTD1J`qJ6 zpTMu!{j$%5I6i^D!}0+kj)b4^lMsHwPeS+!KMCO{{3L|`8{iidba*9xMj^LvfuDr% z6MhoHPxwg)Kj9}K{Dhx`@DqNLm*PLuF}fGxKc9}ocv<{KQCvUg(mxRXh4CLyF2#8k zeZs#q{?oz9@jQb*;a^_&zg>$94nXm9l0M;I$Ml|$hVAJ(MW665jsN_X48V1Q{w@3^ zC?Na~m|kyq3sgY2>EFO_Ul&XMUCHq!-1J91A7^;4WAi`KAIA@_M)=0~>w9b{S+(WXM@(+ z7><|WH%BpFi9Z@%V_;8a4{+&gf5N|N(4lY+rzZEga9+@|p8MK|@UQIo zq!a(rV?2$&0o?I&Ub!up(n_^Fx1cqYwvXI2PI3EHX&wS}R4dL6e!$cQ{{yXDF}oTI zN=J(;lMo87xqVvsC-B*_-?A+vS+E5>{bcGk`0=B|Ut@7R?^&DQ)EH`L+Jc_Je=c0W z!4Ur3z1cxH_Pon!{Bj>Ry<7|TIRqfI`&C!iMR)BWrV17J%h-Dy23r(nt$abkA9$~o zFIYfaa3Fk5Tn?U%=N^Vs`CK<5@RM)bUOW80hSm*>`E8Z83^nlm;Ch{l|JVEb`)~8_ zpM#GxT!yQkhoR4*?}$Q-N!o=9p>;YfyIG;7}NCVsk1N(-Ru1EoKs1&%(@qzy}0Y zs$@rh;}a&2{lc^8;5TX!tJHSd2wWwmJP{yg`L&NLN;jqCqq_h1=Hrlyd*y3pe{n?5 z|5&^|VS2fr7L~iD6utnbL%it)-yNSS+eyXR0IIBFFt4#mbzExT;iwR6wKSTJO2FZ0 zVi_=iKQq0)O?KVMkiUxIT!_;iaJ@Z<|JSAie>{%!oaZAk3bd-M={mui*wu;=ZLP}*anv?iL4;o?1F?mGO)@k#jmIFB!*_|`{H{IF)b7}k~p!eXJ z+J)P69Zy`~su{V}@JkSG8Pz%XFF!V$ zp!>~-kHc zkzSGY3*#1k*$ICR6vld2B&gR`E*>n))wmt{DT1w*;PLK zzV5Gk$_IMh!SlL*P5jVS8hDkd>k*KYJn&+J_{-pJ+Pt~X!e-)E2>_fHb^0hDz^`(n zt&{u^9(&sJSsTA>=R3w^g!3?)3_l3xP{SC0d{9Tdf%~wCpYLblZ(5?I^uEs$dHlkMggoQ{{5-fz)<%Qso zKpHtU(V^M++cM($F9>B0cs|i-)``EA_WQq&EFm?p$L@ELu5Wt{h-Ct&CM_#=;YKwTzYG7;H+%^H9r*R)_p1p1OaE>c z;V1lrpYRiY!cRi@2|o$pC;TLYpYRj@sqfR5>;>WfV*L3LljBS|5&kvsKOlsk@DqL# z!cX`~2tVN`A^e1&@Du+3SkNI6`qMdIA95pkX~3C;@P7yS3xZCIgTUg4cmMzZ07*qo IM6N<$f;AWoasU7T literal 0 HcmV?d00001 diff --git a/brand/projects/faststream-redis-timers/lockup-dark.svg b/brand/projects/faststream-redis-timers/lockup-dark.svg new file mode 100644 index 0000000..8e326e3 --- /dev/null +++ b/brand/projects/faststream-redis-timers/lockup-dark.svg @@ -0,0 +1 @@ + diff --git a/brand/projects/faststream-redis-timers/lockup.svg b/brand/projects/faststream-redis-timers/lockup-light.svg similarity index 100% rename from brand/projects/faststream-redis-timers/lockup.svg rename to brand/projects/faststream-redis-timers/lockup-light.svg diff --git a/brand/projects/faststream-redis-timers/lockup.png b/brand/projects/faststream-redis-timers/lockup.png new file mode 100644 index 0000000000000000000000000000000000000000..1a549c2ae6867a1d67a5c0cf6ad295e6a20a7c7d GIT binary patch literal 2498 zcmZ{mc{tQ-8^>oX$FD36#@Ly$HZi`x04_iHR`{5`~b;E{00P zSW3#ioRFcAIF@W9Le_V>-t+JK{PEo1>vP}N{an}c*C)jaZ_0a8>?8;T;x#ujwgG{_ z?X2txu(NKNtv70{;%;SOhhtSuU+XRkNYlqg)7Pdu1*G9)#UiY%>0_WA zsGIUTuqHJ^Y|c12frvzVdwUEKgZB3RmL`TyH9$B>s)@Cd4@kLD{N>zJ3v(7PAnkCwCRPlu%P*Gr7TyE!U4XI6XuOMPr!Y1ZmfW zS^rcwLG&_VZr?7vy62M$r*_+UY~50p%fYT*KaLbHlr~&;{6#Xo;Fwt<;!v0lUn${l zeYO9X-zGXXMst(7Ifj7oM^e6ax)4{5)K@4L(4asWdGTcV_}*IqmT?rJ0aZ>8#1WeV zgId;OO|9$3mrRq@*0sz^nmO9pRI9=|EH$#rXt)2_ee_DZ$(T2Snl&<{TUZQGxT)X!tG&QaR{Fi&KqdV5xR{YV9!K(^Gw&l z$SV?xd(Ygw+x-N?5XLec$Ox-r_Ydo(U;na)E;G}A?9Wr+CsiA;e^zI!I(Rmau|b{D@^dQtU0AMrJrVwn`-Xfk949*?C5qAlOc)l* z0hHRjf#PN0{aY>{plCi=IKX3GmR`QVXx?75J-rhu`IC&wYC_s?T|qtlba)}$S^fPK zQ~i}Pe@1i-zW!}Sy6E^f!~v$NG{>~dg|~FdXil+64VnV+hIIb>hZ>7}Ve-F|(w zO6#Sk3msBFyx0pR=(YUS#Dz$4vyqo-FcCOtGu6Sj2|d2^G)FXtwUF%-3-l9A<}n3 z8CCu1L*cNa#rv8k#OvR(Tf@iS%!QS%By+S^{qS++*yhardM8&isG zlhz&W$!@$@uVg2$$CcJ9CeMV>qFa%8O?mnlx(rr*?U(ZTLCXZI)l=p*Jl$iRqQgdV zC$OWFxpK);C$EY3%i} zzIorji1Ig`@sSMO0dE;97PNGG+__6f3(R~|ki#iqp^pT{Y+YS;p=`ZM8yl9W(KmPG)MfppluC-U-YtNvVpFM9&bs^trjwi`^r#LI_n} zjUnIEmlOpRG1xyS zA>UZ-W1o^2LczwTY?N)xe37%<~?V!AAM*oxIP_$loccq>b0#z@DfIK)!XWF3SOmc_;T@ z1K%WP^niV9e9k!@?d^$93)Or?m{83AOikX$})( z8YM3PPVV-8KEs%DJ%{_sGSIyxQ+56;65gu*4&^a$YPLsp?es0CuHUK-HivrHyN@;M z|6;ZxH7y(yhjev4YmE*nY%&gaY#?;ui;H|6oGvp?wjW&5(g7@9eB{Bt42Aak&m0(E zvRErARts8rVu{Pto8=?XG-sUeRI5?ra{gAZys;615$r0f z$)AXwE_9aCcj?bmR|s8_Xs@lQorxD#HBEnw4z zAz0e7SSwaEkbvxuZvi8^2J99h-WC14OxPFMa-T$*7^Zo~Q! zfyyPT_}&^n_I5?MOCw`%ToV29&=J(W6YVuBEwI-x(A0K^j>GIe1J1WZZI-F%y|1h~ zhW>tp@cDAVUKaNg7e0eKqnCfNk=B)okbg~qB?@p3FbU2AY%Hf>0}Lr46aFQfq+q2b zux+C?60=(gNVAmU|JcV*kh2_fT3t9;bp8)882l@FE}k;(+6W*U^jHc6GRNVKX;}A! F{{oroW~TrE literal 0 HcmV?d00001 diff --git a/brand/projects/httpware/lockup-dark.svg b/brand/projects/httpware/lockup-dark.svg new file mode 100644 index 0000000..5c827ac --- /dev/null +++ b/brand/projects/httpware/lockup-dark.svg @@ -0,0 +1 @@ + diff --git a/brand/projects/httpware/lockup.svg b/brand/projects/httpware/lockup-light.svg similarity index 100% rename from brand/projects/httpware/lockup.svg rename to brand/projects/httpware/lockup-light.svg diff --git a/brand/projects/httpware/lockup.png b/brand/projects/httpware/lockup.png new file mode 100644 index 0000000000000000000000000000000000000000..276cf56e9bc5a522880a1055bc38e0c5e7dd14a1 GIT binary patch literal 1274 zcmeAS@N?(olHy`uVBq!ia0y~yU}OTaQ#hD`WR&;0i9jkLz$e5NNSkH^o#15GmmO+lppiEak4RN(1OhLfEj_Q@^=?XWQ8f}qgQP~)^ThlGU7QyCZ<8um9Z zI5ar?Z(#WUA7~^3?2p=a6v$I33GxeO`1h}=A>T{?f{}3cJJ@)cSvlC4xLBAN zK{_Iq793z;VA1q+aSW-r^>)_lrd0|84W3V?t%%O8wtoMAUc2>*na_e|TYgq|c6in- z*~aappy1v5PH5rlaQ6FpyZhG2Ir`6MW#V99RA69fU=Uzna$w+y6Jl&+C9Mh=`q18z8ec!x(*x@%wW3hmcWrC)u_55m8I`Mn_vagVvZBR zxt8}B9Thf2vP?XXCg{TC%FGeR>=^rg?iEGNC0C|5kk~AIoCQDdPG!fu+4&aYNpM zm3vsOo|=%t`!rXP$!%qEtcJFQS(K4r=} zsXPy^M_q}6TIQ<0SFh|k z{cZw_^2J@V%kNBm*mv~cRMC42ca$Ve{JH4R{yQ736*I(?3gjoROPwyTp<;deai=rU z{JpE#u3wN;b+fek@#L}u(_6b(2Zi9fA@Opd!uMmFQ=QK9u#}l_?v)G|{o{7m@RQ5C z0x3q%+b3$~&kMEQ=q6MmbmN?ENyCGbm^G6>?k*IboK(8qvrvffZF>5y@1bnRO4Rs0 zKip$I5D{`_x1yz_)YQid1Ap$m@FI-mn8Fe>rj=>V?`-D2sy=yTLBbCqCO@H_l8%2n z7=Cg!-I#MEJ&N7kH%77A>>T^PgggJ{XUr^NZTwc7Xe0mVfL*lm_lxl*Qq6%As(g;{ z`R|I@*T&%PT9A{&QNLsUufjdTx1A@PnSG^Q^5=G+e+zdjZg8}pTv&SG(uA&(WI3yn z_7?|Y6KYh#*Kzsh&Z&*LZSniZ*JC$L;}=v%eTtR3UYLK!D8Z1?WTSAhd}Ht87}dqy zA5y$#KDJ8p*d}@K{x?52gO6PsE+n$QeBaFPtUR^fKVJO5FiYX&E&Fp<)hP=#sy?4o zcf9G)cU!L=0du`|+c=ILmc22#Znc)+<}{XX1}vA2ww*o4#&22PTNGLq&QgBY`b=Bt zR*p}+Yqlz#$cWN*o$y&8doIT&xyNgT9Pc%s(cySwdFZe}iruNRO$@eQ9CW`YetRV_ z;mz@%tDPsrgEJs3n*uo%fh@UIMc49#9KV0rFh}$3Yo!PUBxweghJ??IMM}E2o*8kn cq@;e5U;V=D`|YFmJ~9A-r>mdKI;Vst0E!0{QUCw| literal 0 HcmV?d00001 diff --git a/brand/projects/lite-bootstrap/lockup-dark.svg b/brand/projects/lite-bootstrap/lockup-dark.svg new file mode 100644 index 0000000..62ee12f --- /dev/null +++ b/brand/projects/lite-bootstrap/lockup-dark.svg @@ -0,0 +1 @@ + diff --git a/brand/projects/lite-bootstrap/lockup.svg b/brand/projects/lite-bootstrap/lockup-light.svg similarity index 100% rename from brand/projects/lite-bootstrap/lockup.svg rename to brand/projects/lite-bootstrap/lockup-light.svg diff --git a/brand/projects/lite-bootstrap/lockup.png b/brand/projects/lite-bootstrap/lockup.png new file mode 100644 index 0000000000000000000000000000000000000000..e816ab8e5758f10de255530d4ecb2900732e37ed GIT binary patch literal 1689 zcmZWqX;f1O7Jh89h-MTKG*zkyBG7Uakx*&_3HuHqqJRb!*@8u^ScZg0bWlK1Bvc_R zBBexwLM&KBwl_c!kWID_kThb1u!XQn67qP>%)jZJ^PPLYd(ZvupL@=CGyHs9x9RNF z0RUi|yPH!00H|PP*It)qOErLwQ&9T~vtlIUF;&~fL#$N&Hu?Zg#= zQeqtu;Sd(KVkb^eZu$CJfDZvtS5rq2H7!I1fH%`9|3G_JvVvb z=-!K7-48xumr4uFreDEkd-fL`Vv0vvY7e|e!GFV+4Q(ojo^)M=nyj(O%)t8$r5m{1m5gxieHym#{g@+Dp=Smj+-=%@> z3l*XBp0fAshu_BzS>2*ekNE6A(WE1*l>c7RYN|LwS;s4;Zm`*^Nk6Q1jl)S2+6}fK zi;$O2+P5)$D};LzjQKjyt5tH^B)%c5_y_4fcY+~3M=2W$YQdTb_cC!DB*HlnH}c!I zqn3oJivwj@tAh_?zQ|dh61amjO(|+m3l;;Xj*(+G#O zZe0Y~&aHC?HJl&|)87TV;oDM1;a)xh)~Re?v{x~!F`Xl7I4$nVbVp zc?O?#tKMiy-Xf0NdhY5Us`CNKRKE;Fb+K{k#SzCi#~^Pz;Be4bBDQO(5+Di0qI&5K zJF}nLZCQDqKOf7zZ}bzn!JsxLcS48tp@{KgwiaO*ztEn!Otj|rKTbP>*9T&Aeqk4= z^9I!S&AcW%L{v`=E*u3dyQfkg6=Mm_aEoau`fTd+qi78*_L4ttHqurl*?cCO=pUMx zKWGM>lE_5r-}6w0gu@<&f8=(4R1Z9U67O4<>(|SG9C{8LikR>EnZ2=YuXbFFDGKj) z8+gdN(EY7R5^K{3b2urEbtkRN?pXXKR+hJHJ_E*W0v~<}eBpHUuIN0|0yCD=^!`>c zs;e|**kwRwD{D>GX#OOuo(@tCdft4JK!3jl_r`ajy#>{iqtj7p4lo-Tk+}r3EZ)>u z9{JK^X`5;`>GcI|`?7*qTrsVzVj>z2AG+rr!6ZY(q0#dZAy!vUpz(?mE&azq&bZ+* zFg^z8?PG?$PSbqz`DrJr&*;GQtVII0F$xC-hkY^jC6|i3)1`D>>cEIvy=!%M#DHmn zNI}yoAmicEXjz|RMBYVbrr-uQtJ}QJCC`L2sgaUtbXWDx9BG72M6MYRo%xfQnpy0FDIeKh_*vmH41Fa)(S&1Gp%hTBBC_f; zedxZx?lX4e+FaffTKkGpZ0S_9 znf>x*LR)3-PYm$xcl5B;jA-Ei>NwogmH~_ zTrGo=cZKgrUt58;+*?lb=dg1ZUN9#kcNSI1}A91Ol# zLk~!;i)M&jEPu>3t@k)s6kwVXrP^mZMg%0}B!LW44~mmb19wKg$_@tuNB^MqhX zB>AHu^bGCzK|)fP@75QRbY85~KZPOhu5Xq@WZQ7aC`8}!vZ+T>D@eFaTVGNi6ncY0 z_XLI7CE_Jxb7Gcr4QX~}TaZ@;-7;7$!u{B8PDZ+|j zel-u1Bo6}l_FqD#*HhA)f7ikn8KFgS&bJMNCqE;&M~?vfvQ>?zT{r zVB-p9l4fFWvu}sEazA&q1S*8ZKs>AR0SlJavUY-xq3$Y`7qcLALLld88; zpYs21SR#nqc!>0v%PZKM!#CT_GWWt&pso7fO|wLRFBbgD6K?!#LW1H-5#+)XffWb) XR*rt4w-7k_pEu&}?Bi643%mIj*Li;s literal 0 HcmV?d00001 diff --git a/brand/projects/litestar-sqlalchemy-template/lockup-dark.svg b/brand/projects/litestar-sqlalchemy-template/lockup-dark.svg new file mode 100644 index 0000000..76a3381 --- /dev/null +++ b/brand/projects/litestar-sqlalchemy-template/lockup-dark.svg @@ -0,0 +1 @@ + diff --git a/brand/projects/litestar-sqlalchemy-template/lockup.svg b/brand/projects/litestar-sqlalchemy-template/lockup-light.svg similarity index 100% rename from brand/projects/litestar-sqlalchemy-template/lockup.svg rename to brand/projects/litestar-sqlalchemy-template/lockup-light.svg diff --git a/brand/projects/litestar-sqlalchemy-template/lockup.png b/brand/projects/litestar-sqlalchemy-template/lockup.png new file mode 100644 index 0000000000000000000000000000000000000000..88e40bee4e6a80cbf3ca6fb3185df08a04c2af71 GIT binary patch literal 2499 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 diff --git a/brand/projects/modern-di-fastapi/lockup.svg b/brand/projects/modern-di-fastapi/lockup-light.svg similarity index 100% rename from brand/projects/modern-di-fastapi/lockup.svg rename to brand/projects/modern-di-fastapi/lockup-light.svg diff --git a/brand/projects/modern-di-fastapi/lockup.png b/brand/projects/modern-di-fastapi/lockup.png new file mode 100644 index 0000000000000000000000000000000000000000..a15fb83e51d08a6ccd68364dece010b636606695 GIT binary patch literal 2093 zcmZWqdpOgJ8~@6fD3=ILl1nPNU-FX}LgX^{jzbX^Q7dz+m2Dw%X^#68R#8sKoFrQ3 zw2`}z>%=rBBuASgTJ5`i&(426&+mEO=Y2o7=l%DS?c;rNrz}Di0DztDZq9xHAb}U- zC>crdeqmpqB|hOko&hfJn@)QM2QLoY9if=giNH7sa3DJLW&;3`IM<%aU3w=D_T>Op z(SG6)>sB%U0m~SaWsI*?w69f+?*?yKtoMm02RITG)SCmCU-2C*R$xdpV^6dxyE%EbCZ#M5+vx1cG%?+w9ARzMtI#j4cw85c=VeIt zzRkiIWL9D7|fwt3ZNc#QBGSg_)8jhU(YnFAPU;h2&-k_3UTQN4m|g`#~tF~LqBTudx~ zsKD3irrUmL#@gkN!NGhElCq_XJ(fQT2NgI3%}4BYf@ZZi^M+7$pP~UR(P}#hx)mZ> z(B?-71;TVjJ|)qclQk_ZH7vC_o8m1f?l#P+*U;u9K}Kff^}nCAr8bg2@puyu$GnZm$8`1*%2(r zU1^8@F`t6$&G4!=h`WxP_eZiKKj^;&7d$5a54<@<*;t_e311dpO9v$#PJXFLM-)3=BR55Lz-$` zO$8vU6z3Q@!A;hejO#BV(n~nVJEQchYAArjex7@K zWgz68N3c`capK>!c9ct0QcB>kgtZ;M+IdH4rmx*C3XW>}j$s_X!Lzk3w&3*l&UG8L zQxd@-&hGnr3DLW>pT)CgC3NJ-!c)9P*gd@eneyCyW)o!7%deDTKXAi^m3l(;PGN)3 zscWnTpRhSgyiK}kWZo&$GZU>rLoPK2``oG#HJ&=Ic^)NXC0vnRJEA3E&>gAf(t;3C zuMce+zPW5_;1rr45K+)4LGn_~q`h)YTI(Om)1RJ-Y%a-37F1zwxGj7uJzK{Ot>0>R z+UIvDCA#eFK4~e|;%bdQx_*B6Rh0|BpuCLsjnrbcnJFMCUJlE##Qz->Uh|tdHFpZQ zFFD*1I%jcfx94J7YHINQ^R*Dbt1e2F~(Mm9!o$72jtN`s#s3%*vKqLTI~=O%^h zTTovyOtA>Bg3@b64qgEDu`9?TD zNA6|2#qf$J=S;G8Pd;RxUYf|^B?K10-#?F82@G_eyAkj)y}X-kYpCH7T<>XQ{lk|v zcz|EcNT^;!^=}%=9xvjb@bJ3mSba%Nfqk({nV&SS!kU($2SyDX-ug9WTqD)xwW!lZ-`ita)K{K6m%pi7Z(K$anjQ&keiaAnPuqnh&G&Z2UczR?T&{+D) z&`JKly5DlbP?SKqvG(|4X&3jQDjFeY+qqjb)2`dG%uz_p-41@R?4z1 zFWAYCrO%%As^qq&z*ZpR4$43FGc~J+39P~%lXRi|dxtgGHVXIo(LU|ij^x;9j#2ue z?oXJhdDFEU#ZC{)&OT_>!VPdL6s$uGbHjGtwl{H7T|n7gyx~r(5@PH?0}jLKs`RFQ zg!X)S5_v|aERozv^)Z+&iYHJk!rjQdwXGie)8Egaw?A$^uFuQ!)ac5817N=T3Yd1~ zYXs`)PA+=vm)~>>rTsLd*AJOk%hAUMKdFeU{Y&n(h4Jay5gdFZ0y|^unx@C{1K*_U z->X^8R=E3?fl?g3Ad%tOt*-s;k{Vog5;sLQT=5=gJIJb&QTq02h7;XuyhCQ^ucZ?D z@jGAj7dTpRpWgRNLd!K_*oX*~SV`RYG|S-2THA)Ue@{cx~OcY8lIo(vAG{ z#K>e^v)2f6l1PvOv%mjgi$+b7_L{*#IbIQsznJq@B7qS`LT*gq`&M@o>FUTm1oz)R zEy^;&atI%L`{UN@lZbRhh=23JsG0}F`fSqOLQ$YFX#^mR{Es z{mzJcVLoTV817|JddPwz1Q9w3VbsK3C9W#Tp9|?fF3RSbM8XjOl(LXdvV2>tJO{~x za diff --git a/brand/projects/modern-di-faststream/lockup.svg b/brand/projects/modern-di-faststream/lockup-light.svg similarity index 100% rename from brand/projects/modern-di-faststream/lockup.svg rename to brand/projects/modern-di-faststream/lockup-light.svg diff --git a/brand/projects/modern-di-faststream/lockup.png b/brand/projects/modern-di-faststream/lockup.png new file mode 100644 index 0000000000000000000000000000000000000000..a7b8ee817a243c393d0039673de5be184b650bed GIT binary patch literal 2204 zcmZuydpOg78~!qYd1OFoeoecwA4h4!v7g2R31Aip~BJN81 zRTy`75gU+5`e7~v0>Oev1ZXr1n#B+UctHcUw}FZZV4EiT^*5Tpva2GwE7H~R6tKCK z*h_~TxLE1HQgiIrl@6Db1IdU>NK1%;#6_l*fu?%^Al+?eV~M{s`YnI9v1p%Sf`f&T zUr)ii(v7XEnh|4LhxGh*Y6Z0i2Z=8{L(g!fRDfk=1Nb4TVDH zNg{O-B&6II=f9bhWa2MuF0p~@#rUjg5j>3be=lx^Zb1Q-Jr*<8CjQsPCwzia1_qG z;~bu1y!OS*HZ)jDm~Fqlspr16sRj6rETOvBMhR!NXZhvtLz{gD82h%<>>6)8%=@^M z)%tdxPd~?KNqW@DTc;C{<83qI)^Uyg2Un=#k9E=Mm0Uj`?m8m;GqLor!rh!S&sfkL^T?` zmXb3c4sm>y$1?fB^@q%=geS?LrF<{Q(>4~k=8sE9wcr~pt)ba>8`1io=H8e-ZGG<) zqy-|63>$k-abGbKU%y1h!m&KPh^h7!q^_@pxw5{8Jai(Dx1@7~bfur`y{8H5fh(nD zeubDYRy&-OuqtCG=)SzGeT0ImUZ^UvE%VbGd{BtWa46<=IA*$hMl8#+7$23s*PsH- z+)mo*dEMtx;u8!Gng~0j7I1jySXmy)sX=|;(DRz}`04S8We{AdgoGxgDyc#}e^T9+ zVR^|Ku~?XL$%1Bk{GDJX{BM&oOh*ac!1t~1r1#!TmX*+=Dke&)rG8`J6~J;Fl%4Jq z3r-+w9%Qe35_P|as=PWr7x#DpC#a?%!?f#!gMBS=Yh4*ioHp!9X?Sg#aT^ygV2PQp zS<_h+M0k?U)fC2!ZuI0VVKHiq?IFrw^M`xwZ=3?uIeW(#7J>(GsiADuuEJnbc6%)w-(22_Q9Kp;~F=pt!(fYq(ms z$$edh9i}-sI)XfdI>ML^HCSPtwqYA`QrTs0QaENZqHCU1*oL3zVg$CsNNUUhkYkK# zRcaG?*9KS0yVg~8&oup^E$y2&+{*}bbN0SCWFWG-6(?Ubqk!0?puS6BS=g+*yFoJ= zOP|kFT^LKS61Ys<#+(**wt~6(?t9rg`?kOd9kfA6#(}#pLDe0kVJNoudeZ$qY$fYK znYSG*Hk*Y2gFih$!HyPlQpJ*zMbGkF(gL2uZnsCI=RM*%m zVepsVg>lA!>e|RcCk$qMe$A{$R zpHzd^y*`_A4uD2|fKU=6OD&%S<$$6E`_rrH?3Cffu!ZB?9uw@BOzTnG9zwkjGF}f{ zUT#O!UM>07MP|<3HfYbce@_jMKhPN#7G3NQ^_bL&T9a*Gt@AA~$=MM!V2%Y!@}rIoMa|2P#Ncxkf(9$Z62+h9R2$l|QhiKdD0N{Rm)#$Nl;@>KGZn2cV=K zH2uQrE{}_J7h@aqtLj2Yqfa+0f#Fy=n%MuzLAKMg=zj&v0K)S*&6f<`2?2ot?TGJx sbM${=)ve%8vg}rA@t`PHi6XF`z0gYYBCSNkl>s8y**e-(S`n}R8}Qok&j0`b literal 0 HcmV?d00001 diff --git a/brand/projects/modern-di-litestar/lockup-dark.svg b/brand/projects/modern-di-litestar/lockup-dark.svg new file mode 100644 index 0000000..6a47b2d --- /dev/null +++ b/brand/projects/modern-di-litestar/lockup-dark.svg @@ -0,0 +1 @@ + diff --git a/brand/projects/modern-di-litestar/lockup.svg b/brand/projects/modern-di-litestar/lockup-light.svg similarity index 100% rename from brand/projects/modern-di-litestar/lockup.svg rename to brand/projects/modern-di-litestar/lockup-light.svg diff --git a/brand/projects/modern-di-litestar/lockup.png b/brand/projects/modern-di-litestar/lockup.png new file mode 100644 index 0000000000000000000000000000000000000000..93bc9e0d0c9b19f24e4dfb156061cc8f867932dc GIT binary patch literal 2051 zcmZ9Nc|4SB8^<3;mKMvgO^IQKV}xv34u?5Jwk)AVC{AUILPU$1sbnkWh$7n@6i1pg zwm}%t*fSNHkY-56lFV50;4#lTpY#6pzSrmXxvu;EUBCO^`~VIo z_W}SByzqQp5+UpjHdQIY5$Ji;$6@s43FC{W-xnJ=`T5O{)d55zod^tP0zGK}yZy!= z#6Ol7CxzMGbig#kOQ=;ISGY0__4-$yrXk1v^^Xb7UZK)~o^(LZ*LUE7{MWuL-t3Tz zdYGH=y?U&dyEiNa?|?-m2HcGZls_Vx#4rp(D?5IbRCG+0u7t~3E{aIcq;RYLF}!YYf-7n zQ<8jNKDYSnMsepPce8zqt|)kLbyKipq~AC05X>N4TDOk;!iBm(l!J{y2cgdj9^;(F z@ob0$ap>c^e{TPUl5Y!FU&d@1Yc0R4XKVq2y*$5E)>?_(_V$k9FWoc-;- z)>oy6jtMdEeUAHT8QL^HQw)O+HXU=)F|{0PjQ0M)Hwdj-g5SA3IWdZkKVBD*doG0-s1ai!exd}{g& z;AvpxYmc%skq5LyFh5V;&%Q_+vIx}_SWFw+I~&(Ig33M)k)OYIGda~`T>nLr>Um#C z15(<|Pl#aHc^}~qU2JY$Mt^caBCko{gAdez7&YI0`T3Of^~v0zWM#9~^<4ow)}~0OHG^+%2cmb1r>ag!=^OY@ zs*7{D3Xq$92Z=)6n%U4RmmuuDX?9TMa91Fkl+oF%{oYKv9=t=9PlPMG*Fpy2L&^f# zdgPE(&NbT76>n>-7%~DYu%{u@a6iP%Pwg-Xqqga^0v> zP>_Ug{pJi`w}H}Mx|@08s|MWv*;_IBAMmuC9>9K+H0*>^wiZlF@&3^lkq3RdhT&f-M1gaJbtBQW@8qBzYtTyVg3|YIDT09rp_X zo_R+#cqA%_22qi3C+g@YCf3eaaZq;&?On5xf-=$Z!9F5E4BwF=_`T~Lc^H5Uw&?*v z2qA diff --git a/brand/projects/modern-di-pytest/lockup.svg b/brand/projects/modern-di-pytest/lockup-light.svg similarity index 100% rename from brand/projects/modern-di-pytest/lockup.svg rename to brand/projects/modern-di-pytest/lockup-light.svg diff --git a/brand/projects/modern-di-pytest/lockup.png b/brand/projects/modern-di-pytest/lockup.png new file mode 100644 index 0000000000000000000000000000000000000000..ae04de779c57152f5c0de886846193005514a001 GIT binary patch literal 1749 zcmV;`1}gc9P)PzgBBhCU$p2?0ky2XqLa13I7sI-mnOpaVLf1Ns-Cb8G|LA3DQ^*Mgx#03FaF zfDY&oKnHX{hX6XDLjWDnhxYeid~fKR(+e2i8T#gQ1oS&Yx6A?k&d?omK%WWyk04$z ziobXx@fS}~MwtWpOz8iRynDTWNgmwA+mXZref*E)ag;fr-xGRZ4(NA;9+|g?ZoL&v z42f@B3r>Lk>l4ru^Y+m7&xZcRxMelal@UJydS-q+Egrf$w6fR)`rGSdd0Q`ZY3r>P z1O4?lLte|AFUJ)PFZL&&X;CscMa_OeC+0#w&XUza@5Ssf-8R$2KugVqewxGlv|i}* z<%ZDrbD-}5y$SSR?|;8rdGPxz4}W>t`->CFtNZ=&Pm(7roJGrvtBsUrQR`QsZEP5@Az~1qpU}++T6qHMg z1bxtNT>(NDre#*>oW7*Sy2xH?DnS+{6`rcfhr!}@iO@}7_8yx3?EGlm*cP8Qu^MOSb)x9Oq?9ctQ}u5| zE61DcGW3L@qp#Q$sW_&)oMXfXKOl+QLx1{QoSqQna9PI+W-mHlugZDq;_i9oLBeb$ z3#|ckLyD%v)DI?7QqfiaO#!O*-kR9>lw-sPKWHWFw}U<=Ux99lZXK#ut%vBs)ZbL{ z51@z0r)tmv^kk?iEpVgxCJkwnW5kCT+RE*^pjTk7LDw>i`Fc;+UWJYKbk93`mU{Zo z2Ui~-bm`rypbx?5Jbx9#vN{iduRxEoD~E4$c}zF`(2#rn^4r-AeXMG`7(q6Lz6pCT z`&&TIkw*#}Og&?{s&^qyq_nBfE8F@qbX_z$Pcv#xr__4N4_gssdp3psp?nFtTeoa; zSWTfy?0j8ZFtI%JOA6wrK$o;&O>3!3A!8gWcq&C6iWf{F2g|^$4=%RlWL>35b1l#v zSHJuhX_0DTNI>gz5yNZ|r!F-Sda~Wg!!_s!*@e<#8;L`q7H7?&4{;F}V%!x$r?`u2 zT{z@jO#-p z;lvly>Js$6IJDaY`f_FT)s$#?IHrbPKMWQ0S@QFs%a&*GD(Hg&2++$tpoRyMO6WtY zfL^X%b$<)!XDwNt+WpO;^QI^7GW2t!<>xQIH*_=c%*9;jO^;CiH0ZkRABT(3+a6n8 zHT3TMsESS6wTIsLsPL+x_jfuf-THVopnnKmHa`*%=-=>vjsP9d0UZM9fDY(@4(Nam z=ztFBfDY&@gucJ{fi9rm40`=p^vgs!0eU;=pAbL?bU+7mKnHX{2XsIObU+7mKnL_Y rZUYp8e?)Sx4KK(yZ0$k-eQEMPaR56!YsCjW00000NkvXXu0mjfMP5eA literal 0 HcmV?d00001 diff --git a/brand/projects/modern-di-typer/lockup-dark.svg b/brand/projects/modern-di-typer/lockup-dark.svg new file mode 100644 index 0000000..746ec43 --- /dev/null +++ b/brand/projects/modern-di-typer/lockup-dark.svg @@ -0,0 +1 @@ + diff --git a/brand/projects/modern-di-typer/lockup.svg b/brand/projects/modern-di-typer/lockup-light.svg similarity index 100% rename from brand/projects/modern-di-typer/lockup.svg rename to brand/projects/modern-di-typer/lockup-light.svg diff --git a/brand/projects/modern-di-typer/lockup.png b/brand/projects/modern-di-typer/lockup.png new file mode 100644 index 0000000000000000000000000000000000000000..1c43b0026d77d2d0e539e27ef71e81975e742d50 GIT binary patch literal 1705 zcmZ9Nc~}w#7{X281299d4A9Pec$ta@4xStkM(d-Q`S`m003%eS0o+) z*hi4{kwAHwmS@tnWF-{q?v0wPGCmm^iVg@^<`e;Pb7y{ZL*ybx=>RqzAk$6p>)(IP z8qAele;zHP@iIp90hTfNfARdR(fE%aRxP7(g1Of9l}Xvwf{5qP0E>M@nI)zCez44} zpN#kLk}4@m<)jMjX;xCHD&X%u%GL2p``yi@EmG;U>S3v8#?t0H06_6M8hOS$ZGNp< zkn;MZYTlO@m~DV&>mXgur@^;rA;k#%NfTmojyw1%d*h&iTVd=$Q?`36fE?%owWsU_z1Oq1O^3QiIulp zR>!V`LhV4py;WPC337(CTS@4Ty*P!iS0Om-vQ`oCXn6^e|EX&mz0v7-R+rUS>(FG( zT>{23YOd~X?;hI7EKknn&j$pfH1BqY+ve@gredYK$1dn~WFYyXOQR4Pj*Ed7AneJNf^=>#YHwhm9#D5>DyZHFDJLO?Tbf67I6NB80ZOK+Whf6)Sb#%H zZ}r~J<#m>CKkTw&UdGE3M~=lnbAuQAbSj)8rYEmylDKWbP-|BAEt~fA zIbF$kbB&ch@0>cwHqpPmDK+Ys8ED9=`8D|PSBBS3?x)w*eUDF1nu@Ew>21V!JL??C zkI59|i%hNZxjqVwq;BMi-P?>8`oSlMZz1_{PHbxnrCwyX16y_Oul^ZKpXMkQKM(SH$-23=Qf^iHPwh~>UU zj+J-1e*4`=+oXWKvJre;3LxU@mBx`w+Hb|T55pF-6iECf7ejxAt>9WbH&?Ce00Kz_YVDLi z^Qd~rV`4a85~-EZ;y3Vb3UEF<92^E$dY!Rl_d~W(qx0Aou}>(00oo|zexEWr@28me zajpY(w#Kl#e!}6Ovmv5qXP`kYH;4R5WvE%yH~fNL^DttuS9`&bRSRPB7<<=JZXY^hG<^ zs>pfmWjpPnky{lNtuG);2GEtTRHO&;Ym#*wY+nbvsOV9BcuLHBwL|SoHP~LK!V|Z^ zk(dTfuJXkO8s`4-Bd9eiuR95+3M((s4Tt?|7igDBJW2^GwxZ=P8)2MrzEU#xeYUA0PhWTwputM{IjLBq~-Jw5baA6-}9?72xp@DDqoRCH<^F( zd?Igzfb-jdf`YhWc!iQjb?=QtThsRR8zxCllIX7El*!9NO`>rw`^A;(w)M1yZT3AE zopbzq&6}WNdm!Q2j{y&A#VoiqZ8?HbmM#uHNb;PXqvq(zlW=BZ73 z;Ro#IMz;@&Zwd0WS0J1(152>J_RK9Ht4h6;z!Dt+W-0L9#;-knDL%}8%QDsL&nk+% zM9Q1Sbbz|$B%1uD-NbN4&D#3oe{)b4h5v=5#iy1Ga+Fx6b!K<<2RutX83P9-U^!WM s{-5K#Ph>|CadGV!JFbeQ!T1}!1LFB5-GL&LUVi>2Xp{%C*(sF#56=-VH2?qr literal 0 HcmV?d00001 diff --git a/brand/projects/modern-di/lockup-dark.svg b/brand/projects/modern-di/lockup-dark.svg new file mode 100644 index 0000000..07f4775 --- /dev/null +++ b/brand/projects/modern-di/lockup-dark.svg @@ -0,0 +1 @@ + diff --git a/brand/projects/modern-di/lockup.svg b/brand/projects/modern-di/lockup-light.svg similarity index 100% rename from brand/projects/modern-di/lockup.svg rename to brand/projects/modern-di/lockup-light.svg diff --git a/brand/projects/modern-di/lockup.png b/brand/projects/modern-di/lockup.png new file mode 100644 index 0000000000000000000000000000000000000000..d7dbf030af2b3a3ad2d2b2bbc638a4b0ce56dc17 GIT binary patch literal 1445 zcmYk6c{tPw7{`CEOpeW?k}=h0w8pvaacs#s&an(ap)nYPpP^`y#3iBP_}fVd0|&yj z(e-kU!c83?XFu z9=50;9FQlf|wAAHp5J)V#sX}Gb z@O(;tM3nAC2}hbbC12WW)dWL^1&rW#y<#I&cQ_}AhH|)}0yp;CkYtPMPjXUuy(kn? zcYpsmEYnC;rab1<-*FGmSw+srorIA*hw=uyxt6cMRB87W{D)U=BY6|`rUtqQ>n&KQ zJ^!W$7achta4~Dyt(R!rvEd4;VcL14ruD%;_HTqY2)^lOE_lVqEF2ApZ}F#HO_%C; z9JdFl^n5RrH&nOUb;zQyO0t|-t2bcNaIFFXvdA+(hbtj>@)mw4#MbAz+d>*l=-Rs6 zqipY9`}mQ!*2wliU*J>Ws3$2wtzBMXlA5DUisSgvxwH7!>s^c`dsbh7 zj(QipZMF3yhLrylm0qO7zfiNNJ!ZyK>Ts7_gQ}k|c&NRC82E&ZtA(uIrd4$GC3aKN zPkNPYt=;W3ZBJs)*jHUapY?4?s#42NFQOeWz0~F}H$_8>w3re*prx$UR#9q9L&mjq zY|-Fw!~5fpmhR+?HD5Y5VIe>0?Yd3Mhn*2M_bEq!kHsByJto-iX0kF1w9%+K3I7ZZC-=5lyVpFH?OmyM{c^3FjY7w=N>Of{??Gr8aAUT{-gfj$h+oPs;w zk0_0pqnB`AvKgG`GP={mu9?(We~|q-A*V4#{Juq5L;a&l7mWh+~N~g zd7QEPO@4s}L<-tZABMAZpmAiV%fkOB$u2Z{eA&mZ6he16#B< diff --git a/brand/projects/semvertag/lockup.svg b/brand/projects/semvertag/lockup-light.svg similarity index 100% rename from brand/projects/semvertag/lockup.svg rename to brand/projects/semvertag/lockup-light.svg diff --git a/brand/projects/semvertag/lockup.png b/brand/projects/semvertag/lockup.png new file mode 100644 index 0000000000000000000000000000000000000000..0963f8e8ab93065e3c9c45492f7e33ed107b6b24 GIT binary patch literal 1356 zcmV-S1+)5zP)bXHhh0Q8Z{yHE2@EivY=q z0QB+b%!mL0fPgDkSILS1RaI3$U|>LiKs9hv>e;f$iU81?CGhFhXsji<0000WbW%=J z{{scH|Nj8}{)2#QG0{*Htuxa98UhDR0|*2Q|8M{QH`u}v000DgNklw23w z5C-6Eb{C^)bZD~1r*3=ycUheo91C1q=|h}Pe_~{h&AbLi2;4q(XqEN^g4Q&8!(`+9)?aMjK(p(wrFrRBvO|#&^ap7E?>`@nyyMd9)ii&-^q{$1bN=o@vs8^ib4_Ww zkH%=JY0nOseEDe1q1%${NzZB8rhZf2z?h*HYP2@)1)e4axE`s^sU|M~r&b~JgtH`XV#9oNAQDZkuhO@7KSkD|mwO$v=!(@0~_Zw4}@$I9Dj zQqlhT_V)Jgk5)8C{{;?ygAeQK|4O%c=)4XgElK2`P#desf9)bAUT{S%)VfI7NojrR z(%&hiB%Su;Q$6^v!pjIvzC+zglZ*D#n{Q98Xej5Qbjrq*O@UGm<*iHPXZ&BAp6FDF zxg0v2ABOcYcBE*T-#&c@Yoc*^sPUL6#zLaY#$owx6SFcLHNIjd^iqXN9YrSIdbg?_ zD(wC8kQUqq@XX8@K**x_(YUqb#ktT4jUh6*gX?u_ZHHkK4wcg6^i^(=g39`qV@sxq z6(u=r=R)}omFiLKm=vWu4#P{snj4F^5v5q0v)hojvoy!hlae;??_j<}Bc}JOPWH2V ziuVT%`8pGZ7Or?7T(Xk2`K`t$Ms7Dy`?M2PLyLjSUb*4kf&3>n-D*DUL}8nXcS)aD zuqut?5as!~&_biiQMVjx1g`;dRi~GG!>WoM3r0s~iN-&&tZt2=LxpDaiv{hJhBv+q zn>%S*PfC!AwcCVRq0^u^B&KMIhS;j=vDmx|<+XZWh5|Z*3SKJLG?iu3us-hS&nhh* z^6+?;CZv-_MMDlfy$>xkHg$!vn8%nQDxNUNHBEqq%3_7ulyRIRu;Y5p)9`Ug3RM?E z3k`)|rbs)UMCmbV?pUMPFI(D7n_oSyDW`j+rl)`NG;WoN?VGjGu}bHYSs~f0Qjl&z zb9K9_LTT$pX(FF3?8BnXGb(PrJB>V~NGtCC5rcASq4|ndL)o-B3IAcl=FtZqW!;#w zHr;i$L(w0kxu+fPTTvsWUYrS>(lnA;&je_tJ@fs;R`QLFuLIP)%h% z15LcRrD^dJU0az?LepJy^|G~GLJ*kzJUfbpaBhNKm!`kfCe<6d1#u+Ww{+_ zSessqd%3c`em$BS8fZWR8qk0SG@t1mVz O0000 diff --git a/brand/projects/that-depends/lockup.svg b/brand/projects/that-depends/lockup-light.svg similarity index 100% rename from brand/projects/that-depends/lockup.svg rename to brand/projects/that-depends/lockup-light.svg diff --git a/brand/projects/that-depends/lockup.png b/brand/projects/that-depends/lockup.png new file mode 100644 index 0000000000000000000000000000000000000000..45aacc4de8848ccf886641078c50a982b0812c3a GIT binary patch literal 1648 zcmZ9MX;6~~5Qe`15kZ6i8YlsSV3A7`g{VLYvEdNPWdbTkNDw4a4ImIX`XP}+juujC zVn9@&6glKji6RMvaLHvAL2AX)pr8VQ94$u#Ee#zz)9KF6?z{8u?2rBN7&ZD->AOI zaUc&+x=Kr#0E4li^8x!ff^Bdxj)7ZW2kfGva1=^lVBk6f7`y`1)d3w0<<(DtYv|-C zrD-C;mk50PE0f_9Gu))R*U-OlSj8qrOG6C;-K?szSyfHB)KsgW0|2zl)Aevb^7uk& zbZMoj7UQMa@p=y?jT*JGzW$g^yj@eXFyA~nJ(P&{Pw_dDk=TMi{9cqLQLT^`WY}`j zcEuLN3QuO6VtaBFFyw1In5!e-`OiSMz!ti_goA1=S^_9i^S{={o@K67ebR=R8>`yR z!-0qy6ByZ&cJ#Shsh^HKn_$e{_F@r6Hm%NN6Zbmz7yu5*R(7*H1!0BGf(Q%e9*%4x zMM__clG9N>zs@;vP~M9{5~phhlYcIT75aT}QH<{(mwM{Rp#%rZF>aWj)ZZN2v(jGF za_EsG3Z_z`FbsErl=-fW`$p+^Xo1=xn*@^iem~*y2f5!|-J+3;THq~lRu`*poFn%f ze9b$&iD)K(D(cWdSRW5j5J;`P?KvxhRLOKH6|AGt7$^5oug?+9lWZA^tbJ z7Hl0d|J?qJHeiCzzPN9*K~;M>FhP!yU)(VjfAno{RcBuV{CRhBm6()1IyO1#$U4L> zC0N|dMojJpj|b?rtiAjuJT~lBA zPnW;@Jk=zozJ4}mf0@}@(i2zI<7)?Q$=T)za7x05lJS?Q%NR|>fgqOE&<^r%Ru#Pw zRYBli$jg#A9-NH1&;Mdh5F)E(j8`=znb;xgnSj-?vTcM_vSZ~u5=k8 zP^t~zMmv6EZ=3z(RKeU;S>Be?7l#ddkKd@PGoq7pT8NHpzwUR069c1)fYn=edCiT3 zSvIcRF^Ke{(Vl_j%xe!S&i}|%2-*D>p~Z$=>Omq?xF78M&K!Cwe&xaz>~M#77%` z=-h2ex-^n@e(UtBz@pLbvxaYbqCcCqMh2+)Fugj3AFG?i)3F}=C*lYC*G%90eqhmM z<)kd>y*~zNGv~nXFW3Y{F4!PNCdhf1C>2DXFP0WBy=?TvFb6BIYlCo=1d0w4PI>xyvNMcYaU=7Md4?HT_g s<^~o~mg6c8lDHwt>=lTn=HSp9lwc7bPWqUWwLy4KH(%GrFDV&+1HzFFvH$=8 literal 0 HcmV?d00001 diff --git a/tests/test_lockups.py b/tests/test_lockups.py new file mode 100644 index 0000000..b6f06b2 --- /dev/null +++ b/tests/test_lockups.py @@ -0,0 +1,28 @@ +from pathlib import Path +from xml.dom import minidom + +from PIL import Image + +from brand.build import projects as p +from brand.build import tokens as t + + +def test_light_and_dark_lockup_colourways() -> None: + light = p.project_lockup("modern-di") + dark = p.project_lockup("modern-di", dark=True) + minidom.parseString(light) + minidom.parseString(dark) + assert t.GREEN_INK in light and t.GOLD_LIGHT in light + # dark uses the on-dark colourway: cream + gold-dark, never the dark-green ink + assert t.CREAM in dark and t.GOLD_DARK in dark + assert t.GREEN_INK not in dark + + +def test_render_writes_three_lockup_assets(tmp_path: Path) -> None: + p.render_projects(out_dir=tmp_path) + d = tmp_path / "modern-di" + assert (d / "lockup-light.svg").is_file() + assert (d / "lockup-dark.svg").is_file() + png = d / "lockup.png" + assert png.is_file() + assert Image.open(png).mode == "P" # quantized via export_png From d1420e71444d8ac718542208a098cf0cc2c2998f Mon Sep 17 00:00:00 2001 From: Artur Shiriev Date: Tue, 30 Jun 2026 18:54:58 +0300 Subject: [PATCH 4/5] docs(brand): document README lockups Update stale test to check lockup-light.svg / lockup-dark.svg / lockup.png (the old lockup.svg no longer exists after Task 1 shipped the colourway split). --- architecture/brand-marks.md | 19 +++++++++++++++++++ brand/README.md | 18 ++++++++++++++++-- .../2026-06-30.04-readme-logos/design.md | 2 +- tests/test_projects.py | 5 ++++- 4 files changed, 40 insertions(+), 4 deletions(-) diff --git a/architecture/brand-marks.md b/architecture/brand-marks.md index 606469f..bfb381d 100644 --- a/architecture/brand-marks.md +++ b/architecture/brand-marks.md @@ -25,3 +25,22 @@ All generated PNGs are palette-quantized in `raster.py` (`_quantize_png`, Pillow FASTOCTREE, `_PNG_COLORS` palette) so the committed binaries are indexed-colour and compact; alpha is preserved for the transparent marks. SVGs are left as generated. + +### Lockup colourways and README banners + +Each repo's `brand/projects//` directory contains three lockup files in +addition to `mark.svg` and `mark-512/1024.png`: + +- `lockup-light.svg` — green-ink text + gold accent on transparent background + (for light UIs). +- `lockup-dark.svg` — cream text + gold-dark (`#f0b528`) accent on transparent + background (for dark UIs). This colourway mirrors `wordmark-dark` and the + on-green mark treatment. +- `lockup.png` — the light lockup rasterized and palette-quantized; serves as + the PyPI `` fallback (PyPI renders on a white background, so the light + lockup is the correct choice). + +Repo READMEs embed these as a centered `` banner that replaces the +leading `# ` heading. The `` elements reference the assets via +absolute `raw.githubusercontent.com/modern-python/.github/main/brand/projects//` +URLs so no asset files are committed to the individual repos. diff --git a/brand/README.md b/brand/README.md index 8b00179..6974d6a 100644 --- a/brand/README.md +++ b/brand/README.md @@ -43,8 +43,22 @@ lockup** pulls them into crop marks framing `MODERN` / `PYTHON` set in **Jost** Each repo gets a large-format mark: the constant green+gold snake-frame with one gold inner symbol (see `brand/build/projects.py::MANIFEST`). Regenerate with `uv run python -m brand.build.render`; outputs land in -`brand/projects//` as `mark.svg`, `lockup.svg` (+ PNGs). These are -large-format only — every repo's favicon/avatar stays the org mark. +`brand/projects//` as `mark.svg`, three lockup files (see below), and +PNGs. These are large-format only — every repo's favicon/avatar stays the org mark. + +### Lockup outputs + +Each repo gets three lockup files: + +| File | Colourway | Use | +|------|-----------|-----| +| `lockup-light.svg` | green-ink + gold on transparent | GitHub light theme | +| `lockup-dark.svg` | cream + gold-dark on transparent | GitHub dark theme | +| `lockup.png` | light lockup rasterized + quantized | PyPI fallback (``) | + +The dark colourway (cream + `#f0b528` gold-dark) mirrors the org `wordmark-dark`. +These are used as README banners across the org via a `` element that +references the assets at their `raw.githubusercontent.com` URL in `.github`. Repos with a docs site also get a `social-card.svg` + `social-card.png` (1280×640 og:image): the repo mark on a green panel beside its name, tagline, and docs URL on cream. The docs-site repos are listed in diff --git a/planning/changes/2026-06-30.04-readme-logos/design.md b/planning/changes/2026-06-30.04-readme-logos/design.md index 7203885..0f39030 100644 --- a/planning/changes/2026-06-30.04-readme-logos/design.md +++ b/planning/changes/2026-06-30.04-readme-logos/design.md @@ -1,5 +1,5 @@ --- -summary: Add a centered light/dark logo banner to all 17 repo READMEs, served from .github; generate light/dark/png lockups in brand/build. +summary: README logos shipped — light/dark/png lockups generated in .github; centered banner replaces the H1 in all 17 repo READMEs. --- # Design: README logos diff --git a/tests/test_projects.py b/tests/test_projects.py index 10f8972..5651627 100644 --- a/tests/test_projects.py +++ b/tests/test_projects.py @@ -78,7 +78,10 @@ def test_lockup_is_valid_and_names_repo(repo: str) -> None: def test_render_projects_writes_lockup(tmp_path: Path) -> None: p.render_projects(out_dir=tmp_path) - assert (tmp_path / "modern-di" / "lockup.svg").is_file() + repo_dir = tmp_path / "modern-di" + assert (repo_dir / "lockup-light.svg").is_file() + assert (repo_dir / "lockup-dark.svg").is_file() + assert (repo_dir / "lockup.png").is_file() def test_fit_text_shrinks_only_when_needed() -> None: From 98bc1bea1ef4b0f515044c6b7c3e038d00320749 Mon Sep 17 00:00:00 2001 From: Artur Shiriev Date: Tue, 30 Jun 2026 18:59:16 +0300 Subject: [PATCH 5/5] docs: drop stale lockup.svg reference in brand-marks --- architecture/brand-marks.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/architecture/brand-marks.md b/architecture/brand-marks.md index bfb381d..fd3f88a 100644 --- a/architecture/brand-marks.md +++ b/architecture/brand-marks.md @@ -13,8 +13,9 @@ gold inner symbol (`symbols.py`) chosen per repo in `projects.py::MANIFEST`. Two-colour (green + gold); repos differ by symbol shape, not colour. The two project templates reuse the org chevron. `modern-di-faststream` is the only mark using a partner's literal logo path (FastStream's, recoloured); other -integration cues are redrawn evocations. Outputs: `mark.svg`, `lockup.svg` -(+ `mark-512/1024.png`). Regenerate via `uv run python -m brand.build.render`. +integration cues are redrawn evocations. Outputs: `mark.svg`, +`lockup-light.svg`, `lockup-dark.svg`, `lockup.png` (+ `mark-512/1024.png`). +Regenerate via `uv run python -m brand.build.render`. Repos with a live docs site (`projects.py::DOCS_REPOS`, a subset of `MANIFEST`) additionally get a 1280×640 `social-card.svg|png` — a two-panel og:image (green mark panel + cream name/tagline/url), built with the same frame +