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
@@ -221,8 +221,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";
@@ -345,6 +354,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;
@@ -401,7 +413,11 @@
if (
group.words.length === 1 &&
out.length > 0 &&
out[out.length - 1].words.length < MAX_WORDS_PER_GROUP
out[out.length - 1].words.length < MAX_WORDS_PER_GROUP &&
// makeGroups guards every addition with fitsInTwoLines; this
// second-pass merge must too, or it can produce a group that
// splitLines cannot fit within MAX_LINE_WIDTH.
fitsInTwoLines(out[out.length - 1].words.concat(group.words))
) {
out[out.length - 1] = makeGroup(out[out.length - 1].words.concat(group.words));
} else {
@@ -411,10 +427,18 @@
for (var i = 0; i < out.length; i++) {
if (out[i].words.length !== 1) continue;
if (i + 1 < out.length && out[i + 1].words.length < MAX_WORDS_PER_GROUP) {
if (
i + 1 < out.length &&
out[i + 1].words.length < MAX_WORDS_PER_GROUP &&
fitsInTwoLines(out[i].words.concat(out[i + 1].words))
) {
out[i] = makeGroup(out[i].words.concat(out[i + 1].words));
out.splice(i + 1, 1);
} else if (i > 0 && out[i - 1].words.length < MAX_WORDS_PER_GROUP) {
} else if (
i > 0 &&
out[i - 1].words.length < MAX_WORDS_PER_GROUP &&
fitsInTwoLines(out[i - 1].words.concat(out[i].words))
) {
out[i - 1] = makeGroup(out[i - 1].words.concat(out[i].words));
out.splice(i, 1);
i--;
@@ -464,13 +488,24 @@
function buildCaptions(groups) {
var stage = document.getElementById("caption-stage");
groups.forEach(function (group, groupIndex) {
var groupText = group.words
.map(function (w) {
return w.text.toLowerCase();
})
.join(" ");
// Fit the WIDEST split line, not the joined group text: the group
// renders across up to two lines, so sizing against the joined
// string shrank two-line groups that already fit at full size.
var widestLineText = "";
var widestLineWidth = -1;
group.lines.forEach(function (line) {
var lineWidth = measureLineWidth(line.words);
if (lineWidth > widestLineWidth) {
widestLineWidth = lineWidth;
widestLineText = line.words
.map(function (w) {
return w.text.toLowerCase();
})
.join(" ");
}
});
var computedSize = fitFontSize(
groupText,
widestLineText,
CAPTION_FONT_SIZE,
"700",
"Montserrat",