Convert all Figma theme backgrounds to dark/colored, dedupe again
The 34 kept themes were split 24 light-mode / 18 dark-mode - the light ones all shared the same washed-out near-white background (L=0.95), too bright per feedback. Added a force_mood override to build_theme() and regenerated all 24 as dark instead, same accent character, colored- dark background rather than near-white. That conversion collapsed a lot of previously-distinct light backgrounds into similar dark neutrals, so re-ran the same color-distance dedup pass across the full set: 8 more turned out to be near-twins once everything converged to dark (including a 3-way orange-on-dark cluster trimmed to one). Net: 53 candidates -> 34 kept, all dark/colored, zero white backgrounds - down from the 42 (24 light/18 dark) shipped last commit. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
One-off tool that generated the 53 "website scheme" theme entries in
|
||||
One-off tool behind the 34 "website scheme" theme entries in
|
||||
THEME_PALETTES/THEME_DISPLAY_NAMES (offlineu_core.py), sourced from Figma's
|
||||
"53 Unique Website Color Schemes" resource page:
|
||||
https://www.figma.com/resource-library/website-color-schemes/
|
||||
@@ -8,22 +8,36 @@ That page has no raw hex data - each scheme is a rendered mockup
|
||||
screenshot, not a swatch grid - so website_scheme_swatches.json (checked in
|
||||
alongside this script) holds dominant colors already extracted from those
|
||||
53 images via canvas pixel-histogram sampling in a browser, one entry per
|
||||
scheme: {n, name, colors: [{hex, pct}, ...]}. This script turns that raw
|
||||
scheme: {n, name, colors: [{hex, pct}, ...]}. build_theme() turns that raw
|
||||
material into an actual UI palette per scheme (bg/text/accent, matching
|
||||
THEME_PALETTES' shape), then nudges lightness as needed so every result
|
||||
clears the same contrast bars this file's checks apply: text-vs-background,
|
||||
accent-vs-background, and accent-vs-white (buttons always use white text -
|
||||
see .btn in course_dashboard.html - so a too-bright accent needs catching
|
||||
even when it reads fine against the background alone).
|
||||
THEME_PALETTES' shape), then nudges lightness/saturation as needed so every
|
||||
result clears the same contrast bars this file's checks apply:
|
||||
text-vs-background, accent-vs-background, and accent-vs-white (buttons
|
||||
always use white text - see .btn in course_dashboard.html - so a too-bright
|
||||
accent needs catching even when it reads fine against the background
|
||||
alone), and so accents don't land at the full saturation that reads as
|
||||
neon in the mid-lightness band.
|
||||
|
||||
Not a live pipeline - re-running it regenerates the exact same 53 themes
|
||||
from the same frozen swatch data. To add more schemes, extract their
|
||||
dominant colors the same way (see the canvas-sampling approach used
|
||||
in-session; not scripted here) and append to the JSON, then rerun and
|
||||
splice the output into offlineu_core.py by hand.
|
||||
Running this file directly (see __main__ below) auto-detects each scheme's
|
||||
own mood from its swatches and writes all 53 as candidates - that's NOT
|
||||
what's actually shipped. The source material is mostly light-mode
|
||||
marketing mockups, so the first pass over-represented near-white
|
||||
backgrounds; the shipped 34 all use build_theme(entry, force_mood='dark')
|
||||
instead (every one of the 53 converted to a dark/colored background), then
|
||||
had duplicates pruned by measuring real color distance (hue + lightness +
|
||||
saturation, background and accent both) between every pair, tight enough
|
||||
to only catch genuine near-twins - not something this script's __main__
|
||||
does for you. That curation was one-off analysis, not captured as a single
|
||||
rerunnable command; to redo it, call build_theme(entry, force_mood='dark')
|
||||
per scheme, then de-duplicate the results the same way before splicing
|
||||
into offlineu_core.py by hand.
|
||||
|
||||
To add more schemes: extract their dominant colors the same way (see the
|
||||
canvas-sampling approach used originally; not scripted here) and append to
|
||||
the JSON, then rerun.
|
||||
|
||||
Usage: python3 generate_website_scheme_themes.py
|
||||
Writes generated_themes.json with the full computed palette per scheme.
|
||||
Writes generated_themes.json with all 53 candidates, auto-detected mood.
|
||||
"""
|
||||
import colorsys
|
||||
import json
|
||||
@@ -93,7 +107,7 @@ def tame_accent_saturation(s, l):
|
||||
return min(s, 0.85)
|
||||
|
||||
|
||||
def build_theme(entry):
|
||||
def build_theme(entry, force_mood=None):
|
||||
name = entry['name']
|
||||
swatches = entry['colors']
|
||||
parsed = []
|
||||
@@ -107,8 +121,13 @@ def build_theme(entry):
|
||||
if not content:
|
||||
content = parsed
|
||||
|
||||
darkest_l = min(p['l'] for p in content)
|
||||
is_dark = darkest_l < 0.28
|
||||
if force_mood == 'dark':
|
||||
is_dark = True
|
||||
elif force_mood == 'light':
|
||||
is_dark = False
|
||||
else:
|
||||
darkest_l = min(p['l'] for p in content)
|
||||
is_dark = darkest_l < 0.28
|
||||
|
||||
accent_candidates = [p for p in content if p['s'] > 0.25]
|
||||
if accent_candidates:
|
||||
|
||||
Reference in New Issue
Block a user