diff --git a/.claude/skills/logo/SKILL.md b/.claude/skills/logo/SKILL.md index 536dc9a..fd4bb21 100644 --- a/.claude/skills/logo/SKILL.md +++ b/.claude/skills/logo/SKILL.md @@ -17,8 +17,8 @@ neon hero; otherwise keep text to a minimum. An app-icon-style **glossy dark-glass badge** holding a **neon-green hero glyph** with a soft neon glow, the repo name set beneath. Modern / techy, dark neon aesthetic, suitable as an app icon / favicon. The dark-glass badge is used -in *both* variants — only the surrounding canvas, the badge's depth treatment, -and the title color change between light and dark. +in *both* variants — the canvas is transparent in both, so only the title +color (and the dark variant's title glow) changes between light and dark. ## What stays the same vs. what changes @@ -55,8 +55,6 @@ minimal-hue philosophy. | Neon bright core | `190, 250, 213` | `#befdd5` | inner glow core | | Deep green | `21, 128, 61` | `#15803d` | light-mode title (contrast on white) | | Glass top → bottom | `34,37,46` → `9,10,13` | `#22252e` → `#090a0d` | badge body gradient | -| Dark canvas top → bottom | `12,13,16` → `6,6,8` | `#0c0d10` → `#060608` | dark variant background | -| Light canvas top → bottom | `251,251,253` → `231,232,236` | `#fbfbfd` → `#e7e8ec` | light variant background | ### Geometry (at 1x; render at 2x supersample, then downscale with LANCZOS) @@ -92,14 +90,14 @@ any hero shape picks up the same glow. | Element | Dark variant | Light variant | |---------|--------------|---------------| -| Canvas | dark gradient + soft radial green pool | light gradient | -| Badge depth | neon green halo behind badge | soft offset drop shadow | +| Canvas | transparent | transparent | | Badge & hero | dark glass + neon glyph | **identical** | | Title | `#86efac` with soft glow | `#15803d`, no glow | -Rationale: the neon halo and glowing title disappear on white, so the light -variant swaps them for a drop shadow and a deeper green that holds contrast; -the badge itself never changes. +Rationale: the badge is a clean cutout on a transparent canvas, so it sits on +whatever page color is behind it. The glowing neon title vanishes on white, so +the light variant swaps it for a deeper green that holds contrast; the badge +itself never changes. ## How to build diff --git a/.claude/skills/logo/make_logo.py b/.claude/skills/logo/make_logo.py index 667abd1..e2fee98 100644 --- a/.claude/skills/logo/make_logo.py +++ b/.claude/skills/logo/make_logo.py @@ -82,8 +82,6 @@ def draw_hero(md, box, neon): W, H = 1590 * SS, 1098 * SS # palette -BG_TOP, BG_BOT = (12, 13, 16), (6, 6, 8) # dark canvas gradient -LIGHT_TOP, LIGHT_BOT = (251, 251, 253), (231, 232, 236) # light canvas gradient GLASS_TOP, GLASS_BOT = (34, 37, 46), (9, 10, 13) # dark-glass badge gradient NEON = (134, 239, 172) # #86efac signature neon green (hero + dark title) NEON_BRIGHT = (190, 250, 213) # lighter core that sells the glow @@ -130,44 +128,17 @@ def vgrad(top, bot): def render(theme): """Render one variant; ``theme`` is ``'light'`` or ``'dark'``.""" - # --- canvas --- - if theme == "light": - img = vgrad(LIGHT_TOP, LIGHT_BOT).convert("RGBA") - else: - img = vgrad(BG_TOP, BG_BOT).convert("RGBA") - lift_mask = Image.new("L", (W, H), 0) # soft radial pool of light - ImageDraw.Draw(lift_mask).ellipse( - [ - W // 2 - 520 * SS, - int(H * 0.42) - 380 * SS, - W // 2 + 520 * SS, - int(H * 0.42) + 380 * SS, - ], - fill=70, - ) - lift_mask = lift_mask.filter(ImageFilter.GaussianBlur(220 * SS)) - img.paste(Image.new("RGBA", (W, H), (26, 40, 32, 255)), (0, 0), lift_mask) - + # --- transparent canvas: the badge is a clean cutout with no + # backdrop, so the README shows it over whatever page color sits + # behind it. Only the title color (and the dark variant's title + # glow) changes per theme. --- + img = Image.new("RGBA", (W, H), (0, 0, 0, 0)) draw = ImageDraw.Draw(img) # The badge uses the FIXED module-level geometry (BADGE_BOX) in every # variant, so the central glass rectangle is the exact same size and # position regardless of theme, hero, or title. - # --- depth behind the badge: shadow (light) or neon halo (dark) --- - if theme == "light": - shadow = Image.new("RGBA", (W, H), (0, 0, 0, 0)) - ImageDraw.Draw(shadow).rounded_rectangle( - [BADGE_X0, BADGE_Y0 + 16 * SS, BADGE_X1, BADGE_Y1 + 16 * SS], - BADGE_RADIUS, - fill=(20, 24, 30, 90), - ) - img.alpha_composite(shadow.filter(ImageFilter.GaussianBlur(46 * SS))) - else: - halo = Image.new("RGBA", (W, H), (0, 0, 0, 0)) - ImageDraw.Draw(halo).rounded_rectangle(BADGE_BOX, BADGE_RADIUS, fill=(*NEON, 90)) - img.alpha_composite(halo.filter(ImageFilter.GaussianBlur(55 * SS))) - # --- glass body (dark in BOTH themes) --- mask = Image.new("L", (W, H), 0) ImageDraw.Draw(mask).rounded_rectangle(BADGE_BOX, BADGE_RADIUS, fill=255) @@ -181,9 +152,9 @@ def render(theme): fill=(255, 255, 255, 26), ) gloss = gloss.filter(ImageFilter.GaussianBlur(26 * SS)) - img.paste( - gloss, (0, 0), Image.composite(gloss.getchannel("A"), Image.new("L", (W, H), 0), mask) - ) + # clip the sheen to the badge, then composite so the glass stays opaque + gloss.putalpha(Image.composite(gloss.getchannel("A"), Image.new("L", (W, H), 0), mask)) + img.alpha_composite(gloss) # --- neon hairline border --- draw.rounded_rectangle(BADGE_BOX, BADGE_RADIUS, outline=(*NEON, 70), width=2 * SS) @@ -216,7 +187,7 @@ def render(theme): img.alpha_composite(glow.filter(ImageFilter.GaussianBlur(14 * SS))) draw.text((tx, ty), TITLE, font=font, fill=NEON) - out = img.convert("RGB").resize((1590, 1098), Image.LANCZOS) + out = img.resize((1590, 1098), Image.LANCZOS) # keep alpha path = f"logo-{theme}.png" out.save(path) print("saved", path) diff --git a/logo-dark.png b/logo-dark.png index 4df82fd..db5c5ab 100644 Binary files a/logo-dark.png and b/logo-dark.png differ diff --git a/logo-light.png b/logo-light.png index 41f28d0..78cd7db 100644 Binary files a/logo-light.png and b/logo-light.png differ