CtrlK
BlogDocsLog inGet started
Tessl Logo

gamussa/reels-producer-skill

Write talking-head scripts and produce Instagram reels and YouTube shorts

94

2.36x
Quality

97%

Does it follow best practices?

Impact

85%

2.36x

Average score across 3 eval scenarios

SecuritybySnyk

Low

Low-risk findings worth noting

Overview
Quality
Evals
Security
Files

card_sources.pyskills/reel-builder/scripts/

#!/usr/bin/env python3
"""Remotion component sources, carried as data so they survive packaging.

GENERATED by sync_card_sources.py — do not edit. The canonical files are
assets/remotion-cards/src/*.tsx; edit those and re-run the sync.

The registry's packager ships .ts and drops .tsx, so these two components never
reached a consumer install and make_cards.py could not render anything. A .py
file ships, so they ride in one and make_cards.py writes them back out when the
originals are absent.
"""

FILES = {
    "Card.tsx": r"""import React from 'react';
import {
  AbsoluteFill,
  Img,
  interpolate,
  spring,
  staticFile,
  useCurrentFrame,
  useVideoConfig,
} from 'remotion';

export type CardProps = {
  kicker: string;
  title: string;
  subtitle: string;
  bg: string;
  accent: string;
  fg: string;
  logo: string;
};

export const defaultCardProps: CardProps = {
  kicker: '',
  title: 'Headline goes here',
  subtitle: '',
  bg: '#0F1D2B',
  accent: '#F26B21',
  fg: '#FFFFFF',
  logo: '',
};

/**
 * A single 9:16 card for talking-head b-roll.
 *
 * Motion is deliberately restrained: a card is illustration under a voice, not
 * a title sequence. Everything settles inside the first ~20 frames so a 3s
 * card reads as still-but-alive rather than animating throughout.
 */
export const Card: React.FC<CardProps> = ({
  kicker,
  title,
  subtitle,
  bg,
  accent,
  fg,
  logo,
}) => {
  const frame = useCurrentFrame();
  const {fps, width, height} = useVideoConfig();

  // Scale typography off the frame so 1080 and 2160 renders look identical.
  const unit = width / 1080;
  const enter = spring({frame, fps, config: {damping: 200}});
  const rise = interpolate(enter, [0, 1], [40 * unit, 0]);
  // Slow push keeps a held card from reading as a freeze-frame.
  const drift = interpolate(frame, [0, fps * 6], [1, 1.04], {
    extrapolateRight: 'clamp',
  });

  return (
    <AbsoluteFill style={{backgroundColor: bg, transform: `scale(${drift})`}}>
      <AbsoluteFill
        style={{
          justifyContent: 'center',
          padding: 96 * unit,
          opacity: enter,
          transform: `translateY(${rise}px)`,
        }}
      >
        {logo ? (
          <Img
            src={staticFile(logo)}
            style={{
              width: 260 * unit,
              objectFit: 'contain',
              marginBottom: 48 * unit,
            }}
          />
        ) : null}

        {kicker ? (
          <div
            style={{
              color: accent,
              fontFamily: 'Helvetica, Arial, sans-serif',
              fontSize: 40 * unit,
              fontWeight: 700,
              letterSpacing: 6 * unit,
              textTransform: 'uppercase',
              marginBottom: 24 * unit,
            }}
          >
            {kicker}
          </div>
        ) : null}

        <div
          style={{
            color: fg,
            fontFamily: 'Helvetica, Arial, sans-serif',
            fontSize: 96 * unit,
            fontWeight: 800,
            lineHeight: 1.08,
            letterSpacing: -2 * unit,
          }}
        >
          {title}
        </div>

        {subtitle ? (
          <div
            style={{
              color: fg,
              opacity: 0.72,
              fontFamily: 'Helvetica, Arial, sans-serif',
              fontSize: 44 * unit,
              lineHeight: 1.3,
              marginTop: 32 * unit,
            }}
          >
            {subtitle}
          </div>
        ) : null}

        <div
          style={{
            width: interpolate(enter, [0, 1], [0, 180 * unit]),
            height: 10 * unit,
            backgroundColor: accent,
            marginTop: 48 * unit,
          }}
        />
      </AbsoluteFill>
    </AbsoluteFill>
  );
};
""",

    "Root.tsx": r"""import React from 'react';
import {Composition} from 'remotion';
import {Card, CardProps, defaultCardProps} from './Card';

/**
 * One composition, driven entirely by --props from make_cards.py.
 *
 * Width/height/duration come from the CLI too (--width/--height/--frames), so
 * cards match whatever mezzanine spec the project was normalized at.
 */
export const RemotionRoot: React.FC = () => {
  return (
    <Composition
      id="Card"
      component={Card as React.FC<Record<string, unknown>>}
      durationInFrames={90}
      fps={30}
      width={1080}
      height={1920}
      defaultProps={defaultCardProps as unknown as Record<string, unknown>}
    />
  );
};

export type {CardProps};
""",

}

.mcp.json

tile.json