fix(registry): liberal emoji-pop brand colors, weight-shift fit fixes, 8192 clamp

- caption-emoji-pop: shadowForColor now builds its glow via color-mix()
  instead of hex-pair slicing, so the strict 6-digit brand-color gate is
  gone — any CSS color the sibling templates accept (#fff, rgb(), named)
  now renders instead of silently falling back to the default palette

- caption-weight-shift: fitFontSize now sizes against the WIDEST split
  line rather than the joined group text (two-line groups no longer shrink
  unnecessarily), and avoidSingleWordGroups' merges re-check fitsInTwoLines
  like makeGroups' first pass does (merged groups can no longer overflow
  the split budget)

- all 5: hfApplyStageConfig clamps resolution to the published validator's
  <=8192 bound (validator is optional pre-flight; unbounded stages OOM
  render workers), and fit floors carry a comment documenting that the
  minimum size is returned unverified by design

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
vanceingalls
2026-07-24 06:10:00 +00:00
co-authored by Claude Fable 5
parent 5c2981d066
commit 8bf939043f
5 changed files with 117 additions and 40 deletions
+29 -23
View File
@@ -229,8 +229,17 @@
function hfApplyStageConfig(data, durationS) {
var res = (data && data.resolution) || HF_DEFAULT_RESOLUTION;
var W = Math.max(1, Math.round(Number(res.width) || HF_DEFAULT_RESOLUTION.width));
var H = Math.max(1, Math.round(Number(res.height) || HF_DEFAULT_RESOLUTION.height));
// Mirror the published validator's <=8192 bound defensively — the
// validator is an optional pre-flight, and an unbounded stage size
// would OOM render workers.
var W = Math.min(
8192,
Math.max(1, Math.round(Number(res.width) || HF_DEFAULT_RESOLUTION.width)),
);
var H = Math.min(
8192,
Math.max(1, Math.round(Number(res.height) || HF_DEFAULT_RESOLUTION.height)),
);
var root = document.getElementById(HF_ROOT_ID);
[document.documentElement, document.body, root].forEach(function (el) {
el.style.width = W + "px";
@@ -532,6 +541,9 @@
function fitFontSize(text, baseFontSize, fontWeight, fontFamily, maxWidth) {
var size = baseFontSize;
var minSize = Math.floor(baseFontSize * 0.45);
// minSize is a hard floor returned unverified below — self-heal
// accepts residual overflow at the floor (clipped by the stage)
// rather than shrinking below legibility.
while (size > minSize) {
_fitCtx.font = fontWeight + " " + size + "px " + fontFamily;
if (_fitCtx.measureText(text).width <= maxWidth) return size;
@@ -605,24 +617,16 @@
}
function shadowForColor(color) {
var hex = color.replace("#", "");
var r = parseInt(hex.slice(0, 2), 16);
var g = parseInt(hex.slice(2, 4), 16);
var b = parseInt(hex.slice(4, 6), 16);
// color-mix handles ANY CSS color (hex of either length, rgb()/hsl(),
// named colors) — the old hex-pair slicing was why brand colors were
// gated behind a strict 6-digit regex, silently dropping payloads the
// sibling templates accept.
return (
"0 4px 8px rgba(0,0,0,0.7), 0 0 2px rgba(" +
r +
"," +
g +
"," +
b +
",1), 0 0 8px rgba(" +
r +
"," +
g +
"," +
b +
",0.6)"
"0 4px 8px rgba(0,0,0,0.7), 0 0 2px " +
color +
", 0 0 8px color-mix(in srgb, " +
color +
" 60%, transparent)"
);
}
@@ -689,12 +693,14 @@
stage.style.bottom = Math.round(80 * layout.scaleY) + "px";
var rootEl = document.getElementById(HF_ROOT_ID);
// Any non-empty CSS color is honored (mirrors caption-pill-karaoke) —
// shadowForColor no longer needs parseable hex, so the old 6-digit
// gate (which silently dropped #fff / rgb() / named colors that the
// sibling templates accept) is gone.
var primary = getComputedStyle(rootEl).getPropertyValue("--hf-caption-primary").trim();
var accent = getComputedStyle(rootEl).getPropertyValue("--hf-caption-accent").trim();
hfPrimaryColor = /^#[0-9a-f]{6}$/i.test(primary) ? primary : "#FFFFFF";
hfAccentColors = /^#[0-9a-f]{6}$/i.test(accent)
? [accent]
: ["#FF76FF", "#FF0002", "#B2F7FF"];
hfPrimaryColor = primary || "#FFFFFF";
hfAccentColors = accent ? [accent] : ["#FF76FF", "#FF0002", "#B2F7FF"];
var WORDS = normalizeWords(words);
var GROUPS = makeGroups(WORDS);