agentsclimarketplace

Design obs alert overlay

Skill slogsdon/skills-design/skills/design-obs-alert-overlay

Twenty-three brand-agnostic design templates for Claude Code: LinkedIn, Instagram, YouTube, Twitch, blog hero, podcast.

Install
npx -y skills add slogsdon/skills-design --skill design-obs-alert-overlay

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 3 stars3 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Generate an OBS browser-source alert overlay — single 1920×1080 HTML file with TRANSPARENT background and hash-routed scenes for stream events (#follow, #sub, #donation, #raid). Each scene auto-plays a single entrance animation, holds, then fades. Reads ./design/<brand-slug>/DESIGN.md, tokens.css, and components.html. Triggers include "obs alert overlay", "stream alerts", "follower alert", "/obs-alert-overlay".

SKILL.md

12.8 KB, as published. Nobody here has run it

Skill: obs-alert-overlay

Produces ONE self-contained obs-alert-overlay.html file at 1920×1080 with transparent background that streams compositors (OBS, Streamlabs, Twitch Studio) load as a browser source. The page contains four hash-routed scenes — #follow, #sub, #donation, #raid — each with its own auto-playing entrance animation. Switching scenes is just changing the URL hash.

This is distinct from the stream-overlay skill (which produces persistent scene chrome — starting / brb / webcam / lower-third / ending). This skill produces TRANSIENT alert cards triggered per event.

When to use

  • User streams on Twitch / YouTube Live / Kick and wants branded alert cards
  • A DESIGN.md exists for the brand

Inputs

  • Required: brand slug
  • Optional: alert position (default: lower-right corner; alternates: lower-left, upper-right, top-bar)
  • Optional: brand voice for alert copy (e.g. "ack." vs "thanks for the follow." vs "noted." — Shane's brand prefers terse + sentence-case)

Output

./design/<brand-slug>/artifacts/obs-alert-overlay.html (single file — overwrite OK; canonical alert overlay for the brand)

Scenes (default 4)

HashTriggerDefault copy
#follownew follower"<name> just followed."
#subnew subscriber"<name> subscribed."
#donationtip / donation"<name> sent $<amount>."
#raidincoming raid"<name> raided with <count>."

Each scene takes scene parameters via URL: obs-alert-overlay.html#follow?name=Sam (or via OBS alert variable substitution per stream tool).

Steps

1. Verify brand exists

test -f ./design/<brand-slug>/tokens.css

2. Gather the brief

Ask in one message:

1. Default alert position — lower-right (default) | lower-left | upper-right | top-bar
2. Brand voice for alert copy — terse ("noted.") | declarative ("just followed.") | warm ("welcome.")
3. Hold duration (seconds) — default 4
4. Any scenes to skip — default: include all 4

3. Pick variation — applies to ALL scenes (consistency for live broadcasts)

Alert cards must read consistently across scene types — viewers shouldn't have to re-parse the visual language for each event type. Pick ONE set:

  • Card style: bracketed (corner-frame L-marks) | chromeless (no border, type-only) | block (solid color block) | hairline (1px border + cream surface)
  • Type pressure: display-led (Fraunces or brand display dominant) | mono-led (mono labels carry it)
  • Color usage: cream-card (cream surface on transparent overlay) | inverted-card (dark ink card on transparent overlay)
  • Position: lower-right (default) | lower-left | upper-right | top-bar

Differentiation between scenes comes from copy + a small mono label ("FOLLOW" / "SUB" / "TIP" / "RAID"), NOT from changing the visual treatment per scene.

4. Generate the HTML

The file structure mirrors stream-overlay: one .scene per hash, JS reveals the active scene. Each .scene contains an .alert-card with auto-playing CSS keyframe animation.

Template:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title><Brand> — OBS Alert Overlay</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=<families>&display=swap">
<style>
/* Embed tokens.css verbatim */
<contents of tokens.css>

/* Critical: page must be transparent for OBS compositing */
html, body { margin: 0; padding: 0; width: 1920px; height: 1080px; overflow: hidden; background: transparent; font-family: var(--type-sans-family); color: var(--color-ink); }

.scene { position: fixed; inset: 0; width: 1920px; height: 1080px; display: none; }
.scene.is-active { display: block; }

/* Alert card — positioned by variation choice */
.alert-card {
  position: absolute;
  /* lower-right default: */
  bottom: 80px; right: 80px;
  min-width: 480px; max-width: 720px;
  padding: 24px 32px;
  background: var(--color-surface);   /* cream-card; or var(--color-ink) for inverted-card */
  color: var(--color-ink);
  border: 1px solid var(--color-rule); /* hairline variation */
  /* Auto-play sequence: slide-in (0–600ms) → hold (600ms–4400ms) → fade (4400–4800ms) */
  animation: alert-sequence 4800ms cubic-bezier(0.2, 0.6, 0.2, 1) forwards;
}

/* Single animation per scene — entrance + hold + exit as one sequence */
@keyframes alert-sequence {
  0%      { transform: translateX(120%); opacity: 0; }     /* off-screen right */
  12%     { transform: translateX(0);    opacity: 1; }     /* slid in by ~600ms */
  92%     { transform: translateX(0);    opacity: 1; }     /* hold until 4400ms */
  100%    { transform: translateX(0);    opacity: 0; }     /* fade out by 4800ms */
}

/* Alert card structure */
.alert-card .label {
  font-family: var(--type-mono-family);
  font-size: 11px; letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--color-ink-3);
  margin: 0 0 8px;
}
.alert-card .copy {
  font-family: var(--type-display-family);
  font-weight: 500; font-size: 32px; line-height: 1.18;
  letter-spacing: -0.012em;
  margin: 0;
  color: var(--color-ink);
}
.alert-card .copy .name { color: var(--color-accent); }   /* the dynamic name in accent — the only place accent is used */

/* Variant: inverted card */
.alert-card--inverted {
  background: var(--color-ink); color: var(--color-surface);
  border-color: rgba(251, 250, 249, 0.18);
}
.alert-card--inverted .label { color: rgba(251, 250, 249, 0.55); }
.alert-card--inverted .copy { color: var(--color-surface); }

/* Bracketed variation */
.alert-card--bracketed { border: 0; }
.alert-card--bracketed::before, .alert-card--bracketed::after {
  content: ""; position: absolute; width: 12px; height: 12px;
  border: 1px solid var(--color-ink);
}
.alert-card--bracketed::before { top: -1px; left: -1px; border-right: none; border-bottom: none; }
.alert-card--bracketed::after { bottom: -1px; right: -1px; border-left: none; border-top: none; }
</style>
</head>
<body>
<!--
Stream Alert Overlay — single file, hash-routed scenes.
Load as OBS browser source at 1920×1080 (transparent background).
Switch via URL hash:
  #follow · #sub · #donation · #raid
Each scene auto-plays its 4.8s alert sequence on load.
Pass dynamic names via URL query: ?name=Sam&amount=10

Variation choices:
  card-style:    <picked>
  type-pressure: <picked>
  color:         <picked>
  position:      <picked>
-->

<section id="scene-follow" class="scene">
  <div class="alert-card">
    <p class="label">— follow</p>
    <p class="copy"><span class="name">[name]</span> just followed.</p>
  </div>
</section>

<section id="scene-sub" class="scene">
  <div class="alert-card">
    <p class="label">— subscriber</p>
    <p class="copy"><span class="name">[name]</span> subscribed.</p>
  </div>
</section>

<section id="scene-donation" class="scene">
  <div class="alert-card">
    <p class="label">— tip</p>
    <p class="copy"><span class="name">[name]</span> sent $<span class="amount">[amount]</span>.</p>
  </div>
</section>

<section id="scene-raid" class="scene">
  <div class="alert-card">
    <p class="label">— raid</p>
    <p class="copy"><span class="name">[name]</span> raided with <span class="count">[count]</span>.</p>
  </div>
</section>

<script>
function activateScene() {
  var hash = (window.location.hash || '#follow').split('?')[0].slice(1);
  var scenes = document.querySelectorAll('.scene');
  scenes.forEach(function(el) { el.classList.toggle('is-active', el.id === 'scene-' + hash); });
  // Parse URL query for dynamic substitution (name, amount, count)
  var params = new URLSearchParams(window.location.hash.split('?')[1] || '');
  ['name', 'amount', 'count'].forEach(function(key) {
    var val = params.get(key);
    if (!val) return;
    document.querySelectorAll('.scene.is-active .' + key).forEach(function(el) { el.textContent = val; });
  });
}
window.addEventListener('hashchange', activateScene);
activateScene();
</script>
</body>
</html>

5. Document the OBS setup for the user

After writing the file:

OBS alert overlay generated at ./design/<brand-slug>/artifacts/obs-alert-overlay.html.

OBS setup (one alert source per scene):

  1. Sources → Add → Browser
  2. Local file → point to obs-alert-overlay.html
  3. Width: 1920, Height: 1080
  4. URL hash: #follow (or other scene)
  5. Optional dynamic name via query: …/obs-alert-overlay.html#follow?name={user}

Connect your alert provider (Streamlabs / StreamElements) to trigger a refresh of the browser source per event so the animation re-plays.

Variation: <card-style> × <type-pressure> × <color> × <position>.

6. Verify

  • Single file, 1920×1080, transparent body background (CRITICAL — OBS compositing depends on this)
  • All 4 scenes present with .is-active toggle via hash
  • One animation per scene — the slide-in + hold + fade is a single sequence (per anti-patterns §8)
  • No decorative motion outside the alert sequence
  • Variation choice consistent across all 4 scenes
  • Read ../design-anti-patterns.md and verify the artifact violates none of its rules. Pay special attention to §3 (no accent on a single punctuation mark — but accent on the dynamic name token IS allowed because it's doing semantic work, marking the new entity), §5 (no editorial-cosplay markers), and §8 (animation discipline)
  • Dynamic name span uses --color-accent ONLY when the name is the new entity (not as decoration)

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. OBS loads one URL; multiple files would defeat the purpose.
  • Transparent background — hard requirement. body { background: transparent } must be present.
  • One animation per scene. Slide-in + hold + fade is ONE sequence. Adding a separate spinner or pulse would be two animations — forbidden.
  • No sound. This is a visual artifact. Audio belongs to the streaming software's alert config, not the overlay.
  • Dynamic substitution via URL query. Name, amount, count are passed in by the streaming tool — the artifact must accept them via ?name=... parsing.
  • Token-pure. Same rules as other platform skills.
  • 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.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.