Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 36 additions & 10 deletions docs/catalog/blocks/mk-callout-highlight.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { InstallCommand } from "/snippets/install-command.jsx";
title="Word-Sweep Highlight"
description="A sentence whose word-by-word emphasis is driven by a single scalar — tween it to sync the highlight with a voiceover"
variables={[]}
meta={{"duration":8,"width":1920,"height":1080,"category":"Captions","badge":"Stable","codeLines":156}}
meta={{"duration":8,"width":1920,"height":1080,"category":"Captions","badge":"Stable","codeLines":182}}
attribution={{"path":"registry/blocks/mk-callout-highlight","tags":["typography","karaoke","captions","minimal"]}}
hasCode
rawUrl="https://raw.githubusercontent.com/heygen-com/hyperframes/main/registry/blocks/mk-callout-highlight/mk-callout-highlight.html"
Expand Down Expand Up @@ -55,8 +55,20 @@ import { InstallCommand } from "/snippets/install-command.jsx";
overflow: hidden;
background: transparent; /* overlays footage or mk-background */
}
#mk-ch-box {
#mk-ch-center {
/* CSS centring. The box is a flex item of this full-frame wrapper, so its
place is laid out by the browser rather than measured from a DOM rect
taken before web fonts are ready. An explicit CONFIG.x / CONFIG.y turns
that axis into an edge offset (see the script). No pointer-events:none
here: it inherits to the word spans and the contrast audit skips them. */
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
}
#mk-ch-box {
flex: none; /* max-content width, clamped by max-width; never shrunk */
font-family: var(--mk-font);
font-weight: 500;
letter-spacing: -0.015em;
Expand All @@ -75,7 +87,9 @@ import { InstallCommand } from "/snippets/install-command.jsx";
data-width="1920"
data-height="1080"
>
<div id="mk-ch-box" data-layout-allow-occlusion></div>
<div id="mk-ch-center">
<div id="mk-ch-box" data-layout-allow-occlusion></div>
</div>
<div
id="mk-ch-drv"
class="clip"
Expand All @@ -99,7 +113,9 @@ import { InstallCommand } from "/snippets/install-command.jsx";
fontSize: 60,
lineHeight: 1.3,
maxWidth: 700, // px; sentence wraps inside this
x: 1030, // box left edge; null = centered horizontally
x: 1030, // box left edge; null = centered horizontally. Keep x + maxWidth <= 1920:
// the box never shrinks (flex: none), so past the frame edge it is clipped
// by the root's overflow instead of wrapping earlier.
y: null, // box top edge; null = centered vertically
align: "left",
sweep: { start: 1.2, end: 6.2 }, // block-local seconds, linear
Expand Down Expand Up @@ -132,12 +148,19 @@ import { InstallCommand } from "/snippets/install-command.jsx";
wordEls.push(span);
});

/* position (measure after building) */
var rect = box.getBoundingClientRect();
box.style.left =
(CONFIG.x === null ? Math.round((1920 - rect.width) / 2) : CONFIG.x) + "px";
box.style.top =
(CONFIG.y === null ? Math.round((1080 - rect.height) / 2) : CONFIG.y) + "px";
/* position: #mk-ch-center centres the box with flex (no measurement, so the
placement does not depend on font timing). A non-null CONFIG.x / CONFIG.y
switches that axis to an edge offset: the box keeps its content width
(clamped by maxWidth) and is pushed from the frame edge by a margin. */
var center = document.getElementById("mk-ch-center");
if (CONFIG.x !== null) {
center.style.justifyContent = "flex-start";
box.style.marginLeft = CONFIG.x + "px";
}
if (CONFIG.y !== null) {
center.style.alignItems = "flex-start";
box.style.marginTop = CONFIG.y + "px";
}

/* state proxy: GSAP animates st.p, render derives every word color from it */
var st = { p: 0 };
Expand All @@ -152,6 +175,9 @@ import { InstallCommand } from "/snippets/install-command.jsx";

var tl = gsap.timeline({ paused: true });

/* entrance / exit motion stays a GSAP transform on the box itself: the box
carries no CSS transform (centring is flex on the parent), so there is
nothing for the tween to fight. */
if (CONFIG.animationIn) {
gsap.set(box, { opacity: 0, y: 24 });
tl.to(box, { opacity: 1, y: 0, duration: 0.7, ease: "power3.out" }, 0.3);
Expand Down
12 changes: 6 additions & 6 deletions docs/catalog/components/camera-scan-gate.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { InstallCommand } from "/snippets/install-command.jsx";
compositionSrc="compositions/components/camera-scan-gate.html"
title="Camera Scan Gate"
description="A camera and QR recognition moment with a viewfinder sweep, bracket lock, confirmation pulse, and verified next beat."
variables={[{"id":"scanColor","type":"string","role":"style","label":"Scan color","description":"Any CSS color value used by the scan line and recognition glow.","default":"var(--brand)"},{"id":"targetLabel","type":"string","role":"content","label":"Target label","description":"Confirmation label revealed at recognition lock. Blank hides the line.","default":"Verified"},{"id":"sweepSpeed","type":"number","role":"timing","label":"Sweep speed","description":"Speed multiplier for the scan sweep phase only.","default":1,"min":0.8,"max":1.6,"step":0.1,"unit":"x"}]}
variables={[{"id":"scanColor","type":"string","role":"style","label":"Scan color","description":"Any CSS color value used by the scan line and recognition glow.","default":"var(--brand, #22c55e)"},{"id":"targetLabel","type":"string","role":"content","label":"Target label","description":"Confirmation label revealed at recognition lock. Blank hides the line.","default":"Verified"},{"id":"sweepSpeed","type":"number","role":"timing","label":"Sweep speed","description":"Speed multiplier for the scan sweep phase only.","default":1,"min":0.8,"max":1.6,"step":0.1,"unit":"x"}]}
meta={{"category":"Camera","badge":"Stable","codeLines":522}}
attribution={{"path":"registry/components/camera-scan-gate","tags":["prop","ui-props","camera","qr","scan","recognition","interaction","demonstrate"]}}
hasCode
Expand All @@ -40,7 +40,7 @@ import { InstallCommand } from "/snippets/install-command.jsx";
it for passive camera decoration or a generic loading state.

Variables (declared in data-composition-variables below):
- scanColor (string, default "var(--brand)"): any CSS color value used by
- scanColor (string, default "var(--brand, #22c55e)"): any CSS color value used by
the scan line, lock brackets, and confirmation glow.
- targetLabel (string, default "Verified"): label revealed at lock. Empty
string hides the label line entirely.
Expand Down Expand Up @@ -80,7 +80,7 @@ import { InstallCommand } from "/snippets/install-command.jsx";
<html
lang="en"
data-composition-variables='[
{ "id": "scanColor", "type": "string", "role": "style", "label": "Scan color", "description": "Any CSS color value used by the scan line and recognition glow.", "default": "var(--brand)" },
{ "id": "scanColor", "type": "string", "role": "style", "label": "Scan color", "description": "Any CSS color value used by the scan line and recognition glow.", "default": "var(--brand, #22c55e)" },
{ "id": "targetLabel", "type": "string", "role": "content", "label": "Target label", "description": "Confirmation label revealed at recognition lock. Blank hides the line.", "default": "Verified" },
{ "id": "sweepSpeed", "type": "number", "role": "timing", "label": "Sweep speed", "description": "Speed multiplier for the scan sweep phase only.", "default": 1, "min": 0.8, "max": 1.6, "step": 0.1, "unit": "x" }
]'
Expand Down Expand Up @@ -394,7 +394,7 @@ import { InstallCommand } from "/snippets/install-command.jsx";
: {};
var scanColor =
vars.scanColor == null || String(vars.scanColor).trim() === ""
? "var(--brand)"
? "var(--brand, #22c55e)"
: String(vars.scanColor);
var targetLabel = vars.targetLabel == null ? "" : String(vars.targetLabel);
var rawSweepSpeed = Number(vars.sweepSpeed);
Expand Down Expand Up @@ -573,7 +573,7 @@ want to change on the element:

| Variable | Default | Accepts | What it does |
| --- | --- | --- | --- |
| `scanColor` | `var(--brand)` | string | Any CSS color value used by the scan line and recognition glow. |
| `scanColor` | `var(--brand, #22c55e)` | string | Any CSS color value used by the scan line and recognition glow. |
| `targetLabel` | `Verified` | string | Confirmation label revealed at recognition lock. Blank hides the line. |
| `sweepSpeed` | `1` | 0.8x to 1.6x, step 0.1x | Speed multiplier for the scan sweep phase only. |

Expand All @@ -584,7 +584,7 @@ defaults, so this behaves exactly like the preview above until you change one:
<div
data-composition-id="camera-scan-gate"
data-composition-src="compositions/components/camera-scan-gate.html"
data-variable-values='{"scanColor":"var(--brand)","targetLabel":"Verified","sweepSpeed":1}'
data-variable-values='{"scanColor":"var(--brand, #22c55e)","targetLabel":"Verified","sweepSpeed":1}'
></div>
```

Expand Down
2 changes: 1 addition & 1 deletion docs/catalog/components/device-frame-stage.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ import { InstallCommand } from "/snippets/install-command.jsx";
hardware reveal, glare sweep, or camera-lens tour, ever.

This file is a mountable HyperFrames sub-composition (see
skills/hyperframes-core/references/sub-compositions.md): a host
skills/hyperframes/references/format.md): a host
composition embeds it via a clip carrying data-composition-src, a
matching data-composition-id, and its own data-start / data-duration /
data-track-index / data-width / data-height. Everything the render needs
Expand Down
40 changes: 20 additions & 20 deletions docs/catalog/components/focus-swap.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,9 @@ import { InstallCommand } from "/snippets/install-command.jsx";
container-type: size;
isolation: isolate;
overflow: hidden;
background: var(--bg);
color: var(--fg);
font-family: var(--font-body);
background: var(--bg, #070a12);
color: var(--fg, #f8fafc);
font-family: var(--font-body, Inter, system-ui, sans-serif);
}

.fs-clip {
Expand Down Expand Up @@ -121,15 +121,15 @@ import { InstallCommand } from "/snippets/install-command.jsx";
justify-content: space-between;
padding: 5cqh 3.2cqw;
overflow: hidden;
border: 0.16cqw solid var(--border);
border-radius: var(--radius);
background: var(--surface);
box-shadow: 0 2.2cqh 5cqh color-mix(in srgb, var(--bg) 72%, transparent);
border: 0.16cqw solid var(--border, #34405a);
border-radius: var(--radius, 22px);
background: var(--surface, #151c2c);
box-shadow: 0 2.2cqh 5cqh color-mix(in srgb, var(--bg, #070a12) 72%, transparent);
transform-origin: center;
will-change: transform, filter, opacity;
/* Both cards are the same placeholder material. Which one holds
attention is said by blur, scale, and opacity, never by hue. */
--fs-card-accent: color-mix(in srgb, var(--fg) 72%, var(--surface));
--fs-card-accent: color-mix(in srgb, var(--fg, #f8fafc) 72%, var(--surface, #151c2c));
}

.fs-card::before {
Expand All @@ -144,7 +144,7 @@ import { InstallCommand } from "/snippets/install-command.jsx";
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--space-2);
gap: var(--space-2, 16px);
}

.fs-card-letter {
Expand All @@ -153,46 +153,46 @@ import { InstallCommand } from "/snippets/install-command.jsx";
width: 5cqw;
aspect-ratio: 1;
border-radius: 50%;
background: color-mix(in srgb, var(--fg) 13%, var(--surface));
color: var(--fg);
font-family: var(--font-mono);
background: color-mix(in srgb, var(--fg, #f8fafc) 13%, var(--surface, #151c2c));
color: var(--fg, #f8fafc);
font-family: var(--font-mono, ui-monospace, "SF Mono", Menlo, Consolas, monospace);
font-size: 2.3cqw;
font-weight: 700;
}

.fs-status {
color: var(--muted);
font-family: var(--font-mono);
color: var(--muted, #94a3b8);
font-family: var(--font-mono, ui-monospace, "SF Mono", Menlo, Consolas, monospace);
font-size: 1.25cqw;
letter-spacing: 0.12em;
text-transform: uppercase;
}

.fs-copy {
display: grid;
gap: var(--space-1);
gap: var(--space-1, 8px);
}

.fs-title {
color: var(--fg);
font-family: var(--font-display);
color: var(--fg, #f8fafc);
font-family: var(--font-display, Inter, system-ui, sans-serif);
font-size: 3.4cqw;
font-weight: 680;
line-height: 1;
letter-spacing: -0.025em;
}

.fs-detail {
color: var(--muted);
color: var(--muted, #94a3b8);
font-size: 1.45cqw;
line-height: 1.35;
}

.fs-meter {
height: 1.1cqh;
overflow: hidden;
border-radius: var(--radius);
background: color-mix(in srgb, var(--border) 60%, transparent);
border-radius: var(--radius, 22px);
background: color-mix(in srgb, var(--border, #34405a) 60%, transparent);
}

.fs-meter-fill {
Expand Down
2 changes: 1 addition & 1 deletion docs/catalog/components/oversized-cursor.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import { InstallCommand } from "/snippets/install-command.jsx";
mount contract: this file is a HyperFrames sub-composition, loaded by a host via
data-composition-src, never opened standalone. The runtime clones ONLY the
<template> contents into the host slot (see
skills/hyperframes-core/references/sub-compositions.md); everything outside
skills/hyperframes/references/format.md); everything outside
<template>, including this <head>, is discarded at render. The root is #root:
elastic, no data-width/data-height declared here, it fills whatever box the host
clip gives it (position:absolute; inset:0). See demo.html for the mount usage
Expand Down
2 changes: 1 addition & 1 deletion docs/catalog/components/overwhelm-surround.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ import { InstallCommand } from "/snippets/install-command.jsx";
composition. A host loads it via data-composition-src; the runtime only
clones <template> contents (everything outside <template>, including the
entire <head>, is discarded on mount), see
skills/hyperframes-core/references/sub-compositions.md. The root carries no
skills/hyperframes/references/format.md. The root carries no
data-width/data-height: it is elastic, sized off whatever box the host clip
gives it (position:absolute; inset:0; container-type:size), so the effect
reads correctly whether the host mounts it into a 960x540 slot or a full
Expand Down
2 changes: 1 addition & 1 deletion docs/catalog/components/spring-pop.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import { InstallCommand } from "/snippets/install-command.jsx";

Compiled-from evidence: Video Primitives v1 build contract, Easing
vocabulary (--ease-overshoot = GSAP back.out(1.7), taste rules 4 and 5),
plus hyperframes-animation rules/spring-pop-entrance.md's playful
plus hyperframes/animation rules/spring-pop-entrance.md's playful
overshoot variation. This fills the gap left by spring-scale-in, whose
power3.out curve never overshoots.

Expand Down
18 changes: 9 additions & 9 deletions docs/catalog/components/stagger-cascade.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ import { InstallCommand } from "/snippets/install-command.jsx";
container-type: size;
isolation: isolate;
overflow: hidden;
color: var(--fg);
font-family: var(--font-body);
color: var(--fg, #f4f7fb);
font-family: var(--font-body, Inter, system-ui, sans-serif);
}

.sc-clip {
Expand All @@ -117,7 +117,7 @@ import { InstallCommand } from "/snippets/install-command.jsx";
display: grid;
place-items: center;
overflow: hidden;
background: var(--bg);
background: var(--bg, #090d16);
}

.sc-grid {
Expand All @@ -136,10 +136,10 @@ import { InstallCommand } from "/snippets/install-command.jsx";
display: grid;
place-items: center;
overflow: hidden;
border: 0.16cqw solid var(--border);
border: 0.16cqw solid var(--border, rgba(244, 247, 251, 0.14));
border-radius: min(2.4cqw, 4cqh);
background: color-mix(in srgb, var(--surface) 92%, var(--brand));
color: var(--fg);
background: color-mix(in srgb, var(--surface, #171e2d) 92%, var(--brand, #79a8ff));
color: var(--fg, #f4f7fb);
}

.sc-tile::after {
Expand All @@ -150,17 +150,17 @@ import { InstallCommand } from "/snippets/install-command.jsx";
bottom: 12%;
height: min(0.55cqw, 0.95cqh);
border-radius: 50cqw;
background: var(--brand);
background: var(--brand, #79a8ff);
opacity: 0.72;
}

.sc-tile-index {
display: block;
font-family: var(--font-display);
font-family: var(--font-display, Inter, system-ui, sans-serif);
font-size: min(5cqw, 8cqh);
font-weight: 700;
line-height: 1;
color: var(--fg);
color: var(--fg, #f4f7fb);
}
</style>

Expand Down
Loading
Loading