← back to Wallco Ai
fix(recolor): tighten brand-mode prompt so signature accent actually appears
fd353db792e59762de11dba1044d38134473cd31 · 2026-05-25 01:17:05 -0700 · Steve Abrams
First Hermès run (design 39284 → 10158) came back beige/sepia with the
burnt-orange #FF4F00 nowhere visible. Root cause — original v1 prompt
listed hexes in their FASHION_PALETTES.js order (accent first BY LUCK
on some brands, neutral first on others) and only said 'use ONLY these
hexes' without surface-coverage guidance. Gemini balanced toward frequency
and ate the accent.
Three changes:
(a) Pre-classify each hex as accent vs neutral by luminance
(lum<0.08 OR lum>0.94 → neutral). Front-load the prompt with
'SIGNATURE ACCENT IS #FF4F00 (orange)' as the literal first
sentence — Gemini weights early tokens more.
(b) Hard surface-coverage directive: 'MUST cover 15-30% of the
surface as the FOCAL accent', plus explicit negative 'do NOT
bias toward neutrals; do NOT bury the accent under cream/beige'.
(c) Reorder the hex list: accents › neutrals (joined with › to
imply priority order). Add a percentage distribution line
(accent 15-30%, mid 30-50%, neutral remainder).
Also adds a plain-English color-word ('orange', 'red', 'green', etc)
derived from the accent's hue angle so the prompt reads naturally.
Test plan: re-fire hermes on 39284, expect the burnt-orange to dominate
the foreground (tree silhouettes / cactus blades) instead of vanishing.
Files touched
Diff
commit fd353db792e59762de11dba1044d38134473cd31
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Mon May 25 01:17:05 2026 -0700
fix(recolor): tighten brand-mode prompt so signature accent actually appears
First Hermès run (design 39284 → 10158) came back beige/sepia with the
burnt-orange #FF4F00 nowhere visible. Root cause — original v1 prompt
listed hexes in their FASHION_PALETTES.js order (accent first BY LUCK
on some brands, neutral first on others) and only said 'use ONLY these
hexes' without surface-coverage guidance. Gemini balanced toward frequency
and ate the accent.
Three changes:
(a) Pre-classify each hex as accent vs neutral by luminance
(lum<0.08 OR lum>0.94 → neutral). Front-load the prompt with
'SIGNATURE ACCENT IS #FF4F00 (orange)' as the literal first
sentence — Gemini weights early tokens more.
(b) Hard surface-coverage directive: 'MUST cover 15-30% of the
surface as the FOCAL accent', plus explicit negative 'do NOT
bias toward neutrals; do NOT bury the accent under cream/beige'.
(c) Reorder the hex list: accents › neutrals (joined with › to
imply priority order). Add a percentage distribution line
(accent 15-30%, mid 30-50%, neutral remainder).
Also adds a plain-English color-word ('orange', 'red', 'green', etc)
derived from the accent's hue angle so the prompt reads naturally.
Test plan: re-fire hermes on 39284, expect the burnt-orange to dominate
the foreground (tree silhouettes / cactus blades) instead of vanishing.
---
server.js | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 58 insertions(+), 7 deletions(-)
diff --git a/server.js b/server.js
index f1bdedb..e34226d 100644
--- a/server.js
+++ b/server.js
@@ -18915,14 +18915,65 @@ app.post('/api/design/:id/recolor', express.json(), async (req, res) => {
if (!srcPath || !fs.existsSync(srcPath)) return res.status(404).json({ ok: false, error: 'source file missing on disk', srcPath });
const srcB64 = fs.readFileSync(srcPath).toString('base64');
+ // Brand-mode prompt tightening (2026-05-25 follow-up to first Hermès run
+ // which came back beige/sepia with the burnt-orange #FF4F00 nowhere
+ // visible). Three changes vs the v1 brand prompt:
+ // (a) Front-load the SIGNATURE ACCENT hex (first non-near-black,
+ // non-near-white color) — Gemini front-loads attention, so the
+ // accent gets named in the FIRST sentence instead of buried
+ // (b) Hard-require 15-30% surface coverage on the accent + explicitly
+ // say 'do NOT bias toward neutrals'
+ // (c) Reorder the hex list: accents first, neutrals last, joined with
+ // › to imply priority order rather than equality
+ let brandPrompt = '';
+ if (brand) {
+ const lum = (h) => {
+ const r = parseInt(h.slice(1,3),16), g = parseInt(h.slice(3,5),16), b = parseInt(h.slice(5,7),16);
+ return (0.299*r + 0.587*g + 0.114*b) / 255;
+ };
+ const isNeutral = (h) => { const L = lum(h); return L < 0.08 || L > 0.94; };
+ const accents = brand.hex.filter(h => !isNeutral(h));
+ const neutrals = brand.hex.filter(h => isNeutral(h));
+ const ordered = [...accents, ...neutrals];
+ const primaryAccent = accents[0] || brand.hex[0];
+ // Plain-English accent label from hue angle so the prompt reads
+ // '#FF4F00 (orange)' not '#FF4F00 (#FF4F00)'.
+ const accentWord = (() => {
+ const r = parseInt(primaryAccent.slice(1,3),16),
+ g = parseInt(primaryAccent.slice(3,5),16),
+ b = parseInt(primaryAccent.slice(5,7),16);
+ const max = Math.max(r,g,b), min = Math.min(r,g,b), d = max-min;
+ if (d < 12) return 'neutral';
+ let hAng = 0;
+ if (max === r) hAng = ((g-b)/d) % 6;
+ else if (max === g) hAng = (b-r)/d + 2;
+ else hAng = (r-g)/d + 4;
+ hAng *= 60; if (hAng < 0) hAng += 360;
+ if (hAng < 15 || hAng >= 345) return 'red';
+ if (hAng < 45) return 'orange';
+ if (hAng < 70) return 'yellow';
+ if (hAng < 165) return 'green';
+ if (hAng < 200) return 'teal';
+ if (hAng < 260) return 'blue';
+ if (hAng < 290) return 'violet';
+ if (hAng < 330) return 'magenta';
+ return 'pink';
+ })();
+ brandPrompt =
+ `${brand.label.toUpperCase()} FASHION-HOUSE PALETTE — SIGNATURE ACCENT IS ${primaryAccent} (${accentWord}). ` +
+ `The ${accentWord} ${primaryAccent} MUST cover 15-30% of the surface as the FOCAL accent — render it as ` +
+ `the foreground motif silhouettes / the signature highlight / the "this is unmistakably ${brand.label}" color. ` +
+ `Do NOT bias toward neutrals; do NOT bury the accent under cream/beige fill. ` +
+ `Full palette in order of importance: ${ordered.join(' › ')}. ` +
+ `Use ONLY these exact hex colors — no other hues anywhere. ` +
+ `Distribute: ACCENT ${primaryAccent} ≈ 15-30%, mid-tones ≈ 30-50%, neutrals fill the remainder. ` +
+ `Brand signature: ${brand.signature}. ` +
+ `Preserve the motif, composition, and pattern repeat exactly — only colors change. ` +
+ `Seamless tile, no edge artifacts, no signature, no watermark, no text. ` +
+ `High detail, archival quality, fabric-pattern aesthetic — as if printed in ${brand.label}'s own atelier.`;
+ }
const prompt = brand
- ? `Recolor everything into the ${brand.label.toUpperCase()} fashion-house palette ONLY: `
- + `${brand.hex.join(', ')} (${brand.signature}). `
- + `Use ONLY these exact hex colors — no other hues anywhere. Distribute them as a tone-on-tone story, `
- + `with the darkest hex as the deepest motif silhouette, the lightest hex as the ground, and the mid-tones for fill. `
- + `Preserve the motif, composition, and pattern repeat exactly. `
- + `Seamless tile, no edge artifacts, no signature, no watermark, no text. `
- + `High detail, archival quality, fabric-pattern aesthetic — as if printed in ${brand.label}'s own atelier.`
+ ? brandPrompt
: `Recolor everything into the ${hue.label.toUpperCase()} family ONLY. ${hue.tail}. `
+ 'Tone-on-tone: strictly one hue family throughout — no contrasting hues anywhere. '
+ 'Preserve the motif, composition, and pattern repeat exactly. '
← 250dc80 feat(design page): INFO hamburger + buyer drawer next to ADM
·
back to Wallco Ai
·
/designs admin transparency badge + catalog republish + quar 44b3489 →