mirror of
https://github.com/nextlevelbuilder/ui-ux-pro-max-skill.git
synced 2026-09-16 17:16:16 +00:00
fix(brand): apply #497 to the source copy so check:assets passes again
#497 patched cli/assets/skills/brand/scripts/sync-brand-to-tokens.cjs and its test, but sync-assets.mjs mirrors .claude/skills/ into cli/assets/, so the source copy still carried the old adjustBrightness and check:assets reported two stale asset files on main. That check is the first step of both CI workflows, so every PR since then stopped there. Mirror the same two files into the source copy; the diff is byte-identical to #497's. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
d8ce090f82
commit
975cba327e
@ -99,15 +99,34 @@ function generateColorScale(baseHex, darkHex, lightHex) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust hex color brightness
|
||||
* Adjust hex color brightness.
|
||||
*
|
||||
* Blends each channel proportionally toward white (percent > 0) or toward
|
||||
* black (percent < 0) instead of adding/subtracting a flat 255*percent to
|
||||
* every channel. The flat-shift approach clamped all three channels to 0
|
||||
* (or 255) whenever the base color's channels were already low (or high)
|
||||
* relative to the shift — e.g. darkening a dark brand color like #4A3228
|
||||
* by -0.3/-0.45/-0.6 produced #000000 for all three, collapsing shades
|
||||
* 700/800/900 into an identical, useless black.
|
||||
*/
|
||||
function adjustBrightness(hex, percent) {
|
||||
if (typeof hex !== 'string') return '#000000';
|
||||
const num = parseInt(hex.replace('#', ''), 16);
|
||||
const r = Math.min(255, Math.max(0, (num >> 16) + Math.round(255 * percent)));
|
||||
const g = Math.min(255, Math.max(0, ((num >> 8) & 0x00FF) + Math.round(255 * percent)));
|
||||
const b = Math.min(255, Math.max(0, (num & 0x0000FF) + Math.round(255 * percent)));
|
||||
return `#${((r << 16) | (g << 8) | b).toString(16).padStart(6, '0').toUpperCase()}`;
|
||||
const r = (num >> 16) & 0xFF;
|
||||
const g = (num >> 8) & 0xFF;
|
||||
const b = num & 0xFF;
|
||||
|
||||
const adjustChannel = (channel) => {
|
||||
const adjusted = percent >= 0
|
||||
? channel + (255 - channel) * percent
|
||||
: channel * (1 + percent);
|
||||
return Math.min(255, Math.max(0, Math.round(adjusted)));
|
||||
};
|
||||
|
||||
const newR = adjustChannel(r);
|
||||
const newG = adjustChannel(g);
|
||||
const newB = adjustChannel(b);
|
||||
return `#${((newR << 16) | (newG << 8) | newB).toString(16).padStart(6, '0').toUpperCase()}`;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -71,6 +71,40 @@ def test_sync_parses_bundled_starter_template(tmp_path):
|
||||
assert css.exists() and css.stat().st_size > 0
|
||||
|
||||
|
||||
def test_dark_base_color_does_not_collapse_shades_to_black(tmp_path):
|
||||
"""adjustBrightness() used to add/subtract a flat 255*percent per channel.
|
||||
|
||||
For a dark base color (channels already close to 0), darkening by
|
||||
-0.3/-0.45/-0.6 clamped every channel to 0, so shades 700, 800, and 900
|
||||
all came back as the identical, useless #000000 instead of a graded dark
|
||||
scale. This runs the sync against a dark, coffee-roastery-style brand
|
||||
color and asserts the three shades stay distinct and non-black.
|
||||
"""
|
||||
(tmp_path / "docs").mkdir()
|
||||
(tmp_path / "assets").mkdir()
|
||||
shutil.copy(TOKENS_STARTER, tmp_path / "assets" / "design-tokens.json")
|
||||
(tmp_path / "docs" / "brand-guidelines.md").write_text(
|
||||
"## Quick Reference\n\n"
|
||||
"| Element | Value |\n"
|
||||
"|---------|-------|\n"
|
||||
"| Primary Color | #4A3228 |\n"
|
||||
"| Secondary Color | #C08A3E |\n"
|
||||
"| Accent Color | #6B8F71 |\n"
|
||||
)
|
||||
|
||||
result = _run(tmp_path)
|
||||
assert result.returncode == 0, result.stderr + result.stdout
|
||||
|
||||
tokens = json.loads((tmp_path / "assets" / "design-tokens.json").read_text())
|
||||
primary = tokens["primitive"]["color"]["primary"]
|
||||
dark_shades = [primary[shade]["$value"] for shade in ("700", "800", "900")]
|
||||
|
||||
assert len(set(dark_shades)) == 3, (
|
||||
f"expected three distinct dark shades, got {dark_shades}"
|
||||
)
|
||||
assert "#000000" not in dark_shades, dark_shades
|
||||
|
||||
|
||||
def test_reports_missing_guidelines_without_breaking_the_harness(tmp_path):
|
||||
"""The missing-guidelines path is the one that breaks a locale-decoded pipe.
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user