Brand kit: logo, hero, and per-platform social assets
Canonical sources (source/logo.png, source/hero.png) plus generated profile pictures and banners sized for every major platform, favicons, logo masters, and a reproducible build script (tools/build_assets.py). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
75
README.md
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
# Jed Arden — Brand Kit
|
||||
|
||||
Canonical logo, hero image, and ready-to-upload social assets for every major
|
||||
platform. Everything here is generated from two source files so the brand stays
|
||||
consistent wherever it appears.
|
||||
|
||||
| | Source | Style |
|
||||
|---|---|---|
|
||||
| **Logo** | `source/logo.png` | Flat cartoon avatar — red polo, used for all **profile pictures** |
|
||||
| **Hero** | `source/hero.png` | Photoreal triple-monitor desk scene — red polo, used for all **banners / covers** |
|
||||
|
||||
> The logo (flat illustration) and the hero (photoreal render) are intentionally
|
||||
> kept as separate assets rather than composited together — mixing the two styles
|
||||
> in one frame reads as amateurish. Each platform therefore gets a logo-based
|
||||
> profile picture **and** a hero-based banner.
|
||||
|
||||
## Per-platform assets
|
||||
|
||||
Drop these straight into each platform's upload dialog — they're already at the
|
||||
exact required pixel dimensions.
|
||||
|
||||
| Platform | Profile picture | Banner / cover |
|
||||
|---|---|---|
|
||||
| X / Twitter | `avatars/x-400.png` (400×400) | `banners/x-header-1500x500.png` (1500×500) |
|
||||
| LinkedIn (personal) | `avatars/linkedin-400.png` (400×400) | `banners/linkedin-personal-1584x396.png` (1584×396) |
|
||||
| LinkedIn (company) | `avatars/linkedin-400.png` | `banners/linkedin-company-1128x191.png` (1128×191) |
|
||||
| GitHub | `avatars/github-460.png` (460×460) | `banners/github-social-1280x640.png` (1280×640, repo social preview) |
|
||||
| Instagram | `avatars/instagram-320.png` (320×320) | — (no banner) |
|
||||
| Threads | `avatars/threads-320.png` (320×320) | — |
|
||||
| Facebook | `avatars/facebook-320.png` (320×320) | `banners/facebook-cover-851x315.png` (851×315) · 2× `…-2x-1702x630.png` |
|
||||
| YouTube | `avatars/youtube-800.png` (800×800) | `banners/youtube-banner-2560x1440.png` (2560×1440, TV-safe) |
|
||||
| TikTok | `avatars/tiktok-200.png` (200×200) | — |
|
||||
| Mastodon | `avatars/mastodon-400.png` (400×400) | use `banners/open-graph-1200x630.png` |
|
||||
| Bluesky | `avatars/bluesky-400.png` (400×400) | use `banners/twitter-card-1200x628.png` |
|
||||
| Discord | `avatars/discord-512.png` (512×512) | `banners/discord-banner-960x540.png` (960×540) |
|
||||
| Web / Open Graph | `favicon/` set | `banners/open-graph-1200x630.png` (1200×630) · `banners/twitter-card-1200x628.png` |
|
||||
|
||||
### Favicons (`favicon/`)
|
||||
|
||||
`favicon.ico` (multi-res 16–256), `favicon-16/32/48/192/512.png`,
|
||||
`apple-touch-icon-180.png`.
|
||||
|
||||
### Logo masters (`logo/`)
|
||||
|
||||
`logo-original.png` (640²) plus `logo-256/512/1024.png` and the source JPG.
|
||||
Use these when a platform isn't listed above or you need a custom size.
|
||||
|
||||
## Palette
|
||||
|
||||
| Name | Hex | Use |
|
||||
|---|---|---|
|
||||
| Polo Red | `#DC3127` | Primary brand color — accents, links, highlights |
|
||||
| Ink | `#0A0A08` | Outlines, text on light surfaces |
|
||||
| Canvas Cream | `#EFDECC` | Logo background, light surfaces |
|
||||
| Skin Tan | `#F5B079` | Illustration only |
|
||||
| Control-Room Black | `#070506` | Dark surfaces, banner backdrop |
|
||||
|
||||
## Regenerating
|
||||
|
||||
All derived assets are produced from the two sources in `source/`:
|
||||
|
||||
```bash
|
||||
python3 tools/build_assets.py # requires Pillow
|
||||
```
|
||||
|
||||
Edit `source/logo.png` or `source/hero.png` (or the size tables in the script),
|
||||
re-run, and commit. `source/hero-alt.png` is an alternate desk composition kept
|
||||
for reference.
|
||||
|
||||
## Usage & rights
|
||||
|
||||
These are the personal brand assets of Jed Arden. The repository is public so the
|
||||
assets are easy to reference and self-host, but the logo, likeness, and hero
|
||||
imagery are **not** licensed for reuse, redistribution, or derivative works.
|
||||
All rights reserved.
|
||||
BIN
avatars/bluesky-400.png
Normal file
|
After Width: | Height: | Size: 91 KiB |
BIN
avatars/discord-512.png
Normal file
|
After Width: | Height: | Size: 138 KiB |
BIN
avatars/facebook-320.png
Normal file
|
After Width: | Height: | Size: 64 KiB |
BIN
avatars/github-460.png
Normal file
|
After Width: | Height: | Size: 116 KiB |
BIN
avatars/instagram-320.png
Normal file
|
After Width: | Height: | Size: 64 KiB |
BIN
avatars/linkedin-400.png
Normal file
|
After Width: | Height: | Size: 91 KiB |
BIN
avatars/mastodon-400.png
Normal file
|
After Width: | Height: | Size: 91 KiB |
BIN
avatars/threads-320.png
Normal file
|
After Width: | Height: | Size: 64 KiB |
BIN
avatars/tiktok-200.png
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
avatars/x-400.png
Normal file
|
After Width: | Height: | Size: 91 KiB |
BIN
avatars/youtube-800.png
Normal file
|
After Width: | Height: | Size: 280 KiB |
BIN
banners/discord-banner-960x540.png
Normal file
|
After Width: | Height: | Size: 619 KiB |
BIN
banners/facebook-cover-2x-1702x630.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
banners/facebook-cover-851x315.png
Normal file
|
After Width: | Height: | Size: 342 KiB |
BIN
banners/github-social-1280x640.png
Normal file
|
After Width: | Height: | Size: 956 KiB |
BIN
banners/linkedin-company-1128x191.png
Normal file
|
After Width: | Height: | Size: 276 KiB |
BIN
banners/linkedin-personal-1584x396.png
Normal file
|
After Width: | Height: | Size: 771 KiB |
BIN
banners/open-graph-1200x630.png
Normal file
|
After Width: | Height: | Size: 885 KiB |
BIN
banners/twitter-card-1200x628.png
Normal file
|
After Width: | Height: | Size: 882 KiB |
BIN
banners/x-header-1500x500.png
Normal file
|
After Width: | Height: | Size: 898 KiB |
BIN
banners/youtube-banner-2560x1440.png
Normal file
|
After Width: | Height: | Size: 3 MiB |
BIN
favicon/apple-touch-icon-180.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
favicon/favicon-16.png
Normal file
|
After Width: | Height: | Size: 1,020 B |
BIN
favicon/favicon-192.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
favicon/favicon-32.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
favicon/favicon-48.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
BIN
favicon/favicon-512.png
Normal file
|
After Width: | Height: | Size: 138 KiB |
BIN
favicon/favicon.ico
Normal file
|
After Width: | Height: | Size: 76 KiB |
BIN
logo/logo-1024.png
Normal file
|
After Width: | Height: | Size: 410 KiB |
BIN
logo/logo-256.png
Normal file
|
After Width: | Height: | Size: 46 KiB |
BIN
logo/logo-512.png
Normal file
|
After Width: | Height: | Size: 138 KiB |
BIN
logo/logo-original.png
Normal file
|
After Width: | Height: | Size: 189 KiB |
BIN
source/hero-alt.png
Normal file
|
After Width: | Height: | Size: 2 MiB |
BIN
source/hero.png
Normal file
|
After Width: | Height: | Size: 1.6 MiB |
BIN
source/logo.png
Normal file
|
After Width: | Height: | Size: 189 KiB |
119
tools/build_assets.py
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Regenerate every platform asset in the brand kit from the two canonical sources.
|
||||
|
||||
Sources:
|
||||
source/logo.png -- flat cartoon avatar (red polo), used for all profile pictures
|
||||
source/hero.png -- photoreal desk scene (red polo), used for all banners/covers
|
||||
|
||||
Run: python3 tools/build_assets.py
|
||||
"""
|
||||
from PIL import Image
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
SRC = ROOT / "source"
|
||||
LOGO = Image.open(SRC / "logo.png").convert("RGB")
|
||||
HERO = Image.open(SRC / "hero.png").convert("RGB")
|
||||
|
||||
# Brand background (sampled from the logo's cream field) -- used to pad where needed.
|
||||
CREAM = (242, 232, 213)
|
||||
|
||||
|
||||
def save(img, relpath):
|
||||
out = ROOT / relpath
|
||||
out.parent.mkdir(parents=True, exist_ok=True)
|
||||
img.save(out)
|
||||
print(f" {relpath}: {img.size[0]}x{img.size[1]}")
|
||||
|
||||
|
||||
def square(img, size):
|
||||
"""Square profile asset from the (already square) logo."""
|
||||
return img.resize((size, size), Image.LANCZOS)
|
||||
|
||||
|
||||
def cover(img, tw, th, fy=0.45, fx=0.5):
|
||||
"""Scale-to-cover then crop to (tw,th), biased vertically by fy (0=top,1=bottom)."""
|
||||
iw, ih = img.size
|
||||
scale = max(tw / iw, th / ih)
|
||||
nw, nh = round(iw * scale), round(ih * scale)
|
||||
im = img.resize((nw, nh), Image.LANCZOS)
|
||||
left = round((nw - tw) * fx)
|
||||
top = round((nh - th) * fy)
|
||||
return im.crop((left, top, left + tw, top + th))
|
||||
|
||||
|
||||
# ---- Profile pictures (from logo) -------------------------------------------
|
||||
AVATARS = {
|
||||
"avatars/x-400.png": 400,
|
||||
"avatars/linkedin-400.png": 400,
|
||||
"avatars/github-460.png": 460,
|
||||
"avatars/instagram-320.png": 320,
|
||||
"avatars/facebook-320.png": 320,
|
||||
"avatars/youtube-800.png": 800,
|
||||
"avatars/tiktok-200.png": 200,
|
||||
"avatars/mastodon-400.png": 400,
|
||||
"avatars/bluesky-400.png": 400,
|
||||
"avatars/threads-320.png": 320,
|
||||
"avatars/discord-512.png": 512,
|
||||
}
|
||||
|
||||
# ---- Banners / covers (from hero) -------------------------------------------
|
||||
# fy biases the crop band; lower = higher in frame (favours monitors + head).
|
||||
BANNERS = {
|
||||
"banners/x-header-1500x500.png": (1500, 500, 0.42),
|
||||
"banners/linkedin-personal-1584x396.png": (1584, 396, 0.42),
|
||||
"banners/linkedin-company-1128x191.png": (1128, 191, 0.42),
|
||||
"banners/facebook-cover-851x315.png": (851, 315, 0.42),
|
||||
"banners/facebook-cover-2x-1702x630.png": (1702, 630, 0.42),
|
||||
"banners/youtube-banner-2560x1440.png": (2560, 1440, 0.45),
|
||||
"banners/discord-banner-960x540.png": (960, 540, 0.45),
|
||||
"banners/github-social-1280x640.png": (1280, 640, 0.45),
|
||||
"banners/open-graph-1200x630.png": (1200, 630, 0.45),
|
||||
"banners/twitter-card-1200x628.png": (1200, 628, 0.45),
|
||||
}
|
||||
|
||||
# ---- Logo masters & favicons (from logo) ------------------------------------
|
||||
LOGO_SIZES = {
|
||||
"logo/logo-1024.png": 1024,
|
||||
"logo/logo-512.png": 512,
|
||||
"logo/logo-256.png": 256,
|
||||
}
|
||||
FAVICON_SIZES = {
|
||||
"favicon/favicon-16.png": 16,
|
||||
"favicon/favicon-32.png": 32,
|
||||
"favicon/favicon-48.png": 48,
|
||||
"favicon/favicon-192.png": 192,
|
||||
"favicon/favicon-512.png": 512,
|
||||
"favicon/apple-touch-icon-180.png": 180,
|
||||
}
|
||||
|
||||
|
||||
def main():
|
||||
print("avatars:")
|
||||
for path, size in AVATARS.items():
|
||||
save(square(LOGO, size), path)
|
||||
|
||||
print("logo masters:")
|
||||
for path, size in LOGO_SIZES.items():
|
||||
save(square(LOGO, size), path)
|
||||
save(LOGO, "logo/logo-original.png")
|
||||
|
||||
print("favicons:")
|
||||
for path, size in FAVICON_SIZES.items():
|
||||
save(square(LOGO, size), path)
|
||||
# multi-resolution .ico
|
||||
ico = ROOT / "favicon/favicon.ico"
|
||||
LOGO.resize((256, 256), Image.LANCZOS).save(
|
||||
ico, sizes=[(16, 16), (32, 32), (48, 48), (64, 64), (128, 128), (256, 256)]
|
||||
)
|
||||
print(f" favicon/favicon.ico: multi-res")
|
||||
|
||||
print("banners:")
|
||||
for path, (w, h, fy) in BANNERS.items():
|
||||
save(cover(HERO, w, h, fy=fy), path)
|
||||
|
||||
print("done.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||