Install
$ agentstack add skill-slogsdon-skills-design-design-stream-overlay ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Skill: stream-overlay
Produces ONE self-contained stream-overlay.html file at 1920×1080 that contains all the standard live-stream scenes. JavaScript reads the URL hash and shows only the matching scene. OBS / Streamlabs / Twitch Studio loads the file once as a browser source; switching scenes is just changing the hash (e.g. file://.../stream-overlay.html#brb).
When to use
- User streams on Twitch, YouTube Live, Kick, etc. and needs branded overlay scenes
- A
DESIGN.mdexists for the brand
Inputs
- Required: brand slug
- Optional: stream name / show title, social handles to display, scene customization (which scenes to include — defaults to all 5)
Output
./design//artifacts/stream-overlay.html (single file — overwrite OK; the file is the brand's canonical overlay)
Scenes (default 5)
| Hash | Purpose | Layout | |---|---|---| | #starting | "Starting Soon" pre-stream waiting screen | Full-canvas headline + countdown placeholder + brand mark | | #brb | "Be Right Back" mid-stream pause | Full-canvas message + small brand mark, intentionally calm | | #webcam | Webcam frame — sized + positioned for the streamer's webcam capture | Cam window region defined as a transparent cutout with frame around it; rest of canvas shows brand chrome (sidebar with stream title, lower-third with handles) | | #lower-third | Just a lower-third name plate at the bottom — for code-only segments | Bottom 20% of canvas: name + role + handles, rest fully transparent | | #ending | "Thanks for watching" outro screen | Full-canvas thank-you + handles + "Subscribe" prompt (rendered as text, not a button graphic) |
Steps
1. Verify brand exists
test -f ./design//tokens.css
2. Gather the brief
Ask in one message:
1. Stream name / show title (e.g. "Live Coding with Shane" or just leave blank)
2. Social handles to display (Twitter/X, GitHub, website, etc.) — comma-separated
3. Streamer name + role for the lower-third (e.g. "Shane Logsdon · Indie Dev")
4. Webcam position for #webcam scene: top-right | bottom-right | bottom-left | top-left (default: bottom-right)
5. Webcam size: 480x270 | 640x360 | 320x180 (default: 480x270, the typical 16:9 cam window)
6. Any scenes to skip? (default: include all 5)
3. Pick variation (single set, applied across all scenes for coherence)
Unlike single-artifact skills, the overlay must be visually consistent across scenes. Pick variation ONCE for the whole file:
- Chrome style:
hairline(thin rules + restrained type) |bracketed(corner brackets framing each scene) |gridded(subtle grid-paper background) |block(solid color blocks delineating zones) |chromeless(no rules, no brackets — pure type and color) - Type pressure:
display-led(large display type carries scene state) |mono-led(mono labels dominate, very technical feel) - Color usage:
monochrome|single-accent-on-cam-frame|inverted-on-pause-scenes - Brand mark placement:
top-left|bottom-right|top-bar|corner-mark|none(rely on the streamer's voice + camera, not a chrome mark)
Anti-tell guardrails (apply across all scenes):
- Read
../design-anti-patterns.mdand verify scene chrome violates none of its rules. Pay special attention to sections 5 (editorial cosplay markers — no§ 01,EP. 01,Episode), 4 (no top-metadata-row eyebrow disguises across scenes), and 8 (animations — at most ONE functional animation across all scenes; a pulsing dot AND a blinking cursor counts as two). - The pause-scene headline should be a real claim, not a template default ("Starting Soon."/"Right back."/"Thanks for watching." are placeholders — substitute with something brand-voiced if the user supplies a tone).
4. Generate the HTML
Single self-contained file with all scenes as `` elements. JS toggles visibility by hash.
— Stream Overlay
&display=swap">
/* Embed tokens.css verbatim */
html, body { margin: 0; padding: 0; width: 1920px; height: 1080px; overflow: hidden; background: transparent; font-family: var(--type-body-md-family); color: var(--color-ink); }
/* All scenes start hidden; JS reveals the one matching the hash */
.scene { position: fixed; inset: 0; width: 1920px; height: 1080px; display: none; box-sizing: border-box; }
.scene.is-active { display: block; }
/* Full-canvas scenes get a brand surface background */
#scene-starting, #scene-brb, #scene-ending { background: var(--color-surface); }
/* #webcam and #lower-third are transparent — OBS composites the webcam underneath */
#scene-webcam, #scene-lower-third { background: transparent; }
/* Eyebrow / mono label */
.eyebrow {
font: var(--type-label-caps-weight) var(--type-label-caps-size)/var(--type-label-caps-leading) var(--type-label-caps-family);
letter-spacing: var(--type-label-caps-tracking);
text-transform: uppercase;
color: var(--color-ink-soft);
}
/* Display headline */
.headline {
font-family: var(--type-display-xl-family);
font-weight: var(--type-display-xl-weight);
letter-spacing: var(--type-display-xl-tracking);
font-size: clamp(120px, 12vw, 180px);
line-height: 1;
margin: 0;
}
/* Centered scene content (for #starting, #brb, #ending) */
.scene--centered { display: flex; flex-direction: column; align-items: ; justify-content: center; padding: var(--space-4xl); }
/* Webcam frame — transparent inner, framed outer */
.cam-frame {
position: absolute;
/* Position from variation: bottom-right default */
bottom: var(--space-xl);
right: var(--space-xl);
width: 480px; /* matches user-chosen size */
height: 270px;
border: 2px solid var(--color-ink);
background: transparent; /* OBS shows webcam through this */
}
.cam-frame::after {
/* Optional name plate beneath the cam frame */
content: " · ";
position: absolute;
top: 100%; left: 0;
margin-top: var(--space-xs);
font: var(--type-label-caps-weight) var(--type-label-caps-size)/var(--type-label-caps-leading) var(--type-label-caps-family);
letter-spacing: var(--type-label-caps-tracking);
text-transform: uppercase;
color: var(--color-ink);
/* Add a subtle background for legibility over screen content */
background: var(--color-surface);
padding: var(--space-2xs) var(--space-xs);
}
/* Sidebar info column on #webcam scene */
.cam-sidebar {
position: absolute;
top: var(--space-xl);
left: var(--space-xl);
max-width: 320px;
background: var(--color-surface);
padding: var(--space-md);
border: 1px solid var(--color-rule);
}
.cam-sidebar h2 { font: var(--type-headline-sm-weight) var(--type-headline-sm-size)/var(--type-headline-sm-leading) var(--type-headline-sm-family); margin: 0 0 var(--space-xs); }
.cam-sidebar .handles { font-family: var(--type-code-family); font-size: var(--type-body-sm-size); color: var(--color-ink-soft); margin: 0; line-height: 1.6; }
/* Lower-third (used both as standalone scene and inside webcam scene) */
.lower-third {
position: absolute;
bottom: 0; left: 0;
width: 100%;
background: var(--color-ink);
color: var(--color-surface);
padding: var(--space-md) var(--space-xl);
display: flex;
align-items: baseline;
gap: var(--space-xl);
box-sizing: border-box;
}
.lower-third .name { font: var(--type-headline-sm-weight) var(--type-headline-sm-size)/var(--type-headline-sm-leading) var(--type-headline-sm-family); margin: 0; }
.lower-third .role { font-family: var(--type-label-caps-family); letter-spacing: var(--type-label-caps-tracking); text-transform: uppercase; font-size: 14px; opacity: 0.75; }
.lower-third .handles { margin-left: auto; font-family: var(--type-code-family); font-size: var(--type-body-sm-size); opacity: 0.85; }
Starting Soon.
Stream begins shortly · grab a coffee
Right back.
·
Stream ended
Thanks for watching.
Subscribe / follow for next session ·
function activateScene() {
var hash = (window.location.hash || '#starting').slice(1);
var scenes = document.querySelectorAll('.scene');
var matched = false;
scenes.forEach(function(el) {
var isMatch = el.id === 'scene-' + hash;
el.classList.toggle('is-active', isMatch);
if (isMatch) matched = true;
});
if (!matched) {
// Fallback to starting scene if hash doesn't match
document.getElementById('scene-starting').classList.add('is-active');
}
}
window.addEventListener('hashchange', activateScene);
activateScene();
5. Document the OBS setup for the user
After writing the file, give the user a copy-paste setup block:
> Stream overlay generated at ./design//artifacts/stream-overlay.html. > > OBS setup (one-time): > 1. Sources → Add → Browser > 2. Local file → point to stream-overlay.html > 3. Width: 1920, Height: 1080 > 4. Add #starting (or your starting scene hash) to the file URL > > Scene switching: create one OBS scene per hash, each with its own browser source pointing to the same file with a different URL hash: > - …/stream-overlay.html#starting > - …/stream-overlay.html#brb > - …/stream-overlay.html#webcam > - …/stream-overlay.html#lower-third > - …/stream-overlay.html#ending > > The #webcam and #lower-third scenes have transparent backgrounds — composite your webcam / screen capture BENEATH them in OBS. > > Variation: ` × × × `.
6. Verify
- [ ] Single file, 1920×1080, no external deps beyond Google Fonts
- [ ] All 5 scenes present (or whichever subset the user requested)
- [ ]
#webcamand#lower-thirdhavebackground: transparent(critical for OBS compositing) - [ ] Hash JS works — visiting
file://.../stream-overlay.html#brbshows ONLY the BRB scene - [ ] Webcam frame size matches user choice
- [ ] Variation comment present
- [ ] No animated GIFs, no looping CSS animations (distracting for viewers; if requested separately, that's a different artifact)
Anti-Slop Rules
Governed by three shared canonical references — read them, do not restate them:
../design-anti-patterns.md— the hard floor. Wins every conflict.../design-principles.md— the craft floor (typographic hierarchy, spatial rhythm, color theory, layout logic, visual tension).../design-variation-sop.md— the named-aesthetic roster + the procedure for varying every invocation.
Forbidden (fast scan — the references hold the full list):
- Indigo/violet/purple as default accent or primary — the
hsl(230–280)family on a near-white surface. The single loudest AI tell. - Purple→blue / "aurora" / gradient-mesh backgrounds; gradient-fill text.
- Glassmorphism without an explicit AA-contrast scrim; floating gradient "blobs" as atmosphere.
- The three-up icon-card feature grid; the "hero → 3 cards → CTA" median skeleton.
- One global border-radius on every element; timid evenly-weighted low-contrast palette.
- Inter / Roboto / Arial / Open Sans / Lato / Helvetica / system as the primary family (Space Grotesk = yellow flag). Use a category-matched stack from the variation roster.
- Value-free CTAs ("Get Started", "Learn More", "Sign Up"); the two-CTA hero. Name the real action and its value.
Required variation (every invocation):
- Make at least two intentional decisions that differ from the safe defaults (palette, layout structure, typographic voice, or spatial density) AND from the most recent artifact in this brand.
- Never default to "clean / minimal / modern" — that is the absence of a direction (variation-sop Rule 1).
- Sketch three distinct directions, offer them as a one-line menu, generate the best-fit by default, all three only if asked (variation-sop Rule 3).
Authenticity: prefer specific over generic everywhere — real datelines (not "today"), the brand's actual voice (not "build the future" filler), concrete CTAs over placeholders.
Rules
- Single file always. The whole point is OBS loads one URL; multiple files would defeat the purpose.
- Transparent where compositing is needed.
#webcamand#lower-thirdMUST have transparent canvas backgrounds. - At most one functional animation across all scenes. A pulsing status dot OR a blinking cursor — never both. Decorative motion is forbidden.
- Token-pure. Same rules as other platform skills.
- Webcam frame respects user-chosen position and size. Default bottom-right 480×270; honor any other choice.
- Anti-pattern compliance. This skill defers to three shared canonical references:
../design-anti-patterns.md(the hard floor — wins every conflict),../design-principles.md(the craft floor), and../design-variation-sop.md(direction roster + offer-3 procedure). The anti-patterns file is the canonical anti-tell list. If you find a new tell in the output, add it there.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: slogsdon
- Source: slogsdon/skills-design
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.