Cutship
Sign inGet started
← All edits
cutship.ai

Poster · 9:16

Chrome Drop Poster

by CutshipVerified

A Y2K launch poster: bubbly liquid-chrome lettering with a beveled specular sheen and holographic tint, a spinning-badge chrome starburst, glinting sparkles and orbit rings on a midnight ground, with a big chrome date and your handle in the footer.

0 taken · 1 views

Included with Pro

Sign up free to Make this

Sign up free to unlock the spec, agent prompt and Make this.

components/remotion/chrome-drop-poster/component.tsx

import React, { useEffect, useState } from "react";
import { AbsoluteFill, Img, continueRender, delayRender, random, staticFile } from "remotion";
import { loadFont as loadDisplay } from "@remotion/google-fonts/BagelFatOne";
import { loadFont as loadGrotesk } from "@remotion/google-fonts/SpaceGrotesk";
import { getAvailableFonts } from "@remotion/google-fonts";
import type { ChromeDropPosterProps } from "./schema";

const { fontFamily: DISPLAY } = loadDisplay("normal", { weights: ["400"], subsets: ["latin"] });
const { fontFamily: GROTESK } = loadGrotesk("normal", { weights: ["500", "700"], subsets: ["latin"] });

/** Loads a brand-kit Google Font by family name (heaviest weight); returns it once ready. */
const useBrandFont = (family?: string) => {
  const [ready, setReady] = useState<string | null>(null);
  useEffect(() => {
    if (!family) return setReady(null);
    const entry = getAvailableFonts().find((f) => f.fontFamily.toLowerCase() === family.toLowerCase());
    if (!entry) return;
    const handle = delayRender(`Loading font ${family}`);
    entry
      .load()
      .then((mod) => {
        const weights = Object.keys(mod.getInfo().fonts.normal ?? {});
        const heaviest = ["900", "800", "700", "400"].find((w) => weights.includes(w));
        return mod.loadFont("normal", { subsets: ["latin"], weights: heaviest ? [heaviest] : undefined }).waitUntilDone();
      })
      .then(() => setReady(entry.fontFamily))
      .catch(() => setReady(null))
      .finally(() => continueRender(handle));
  }, [family]);
  return ready;
};

const resolveSrc = (src: string) => (src.startsWith("http") || src.startsWith("/") ? src : staticFile(src));

const W = 1080;
const CY = 870;

/** Polished chrome: sky above a dark horizon band, warm ground below. */
const CHROME =
  "linear-gradient(180deg, #ffffff 0%, #eef2fa 14%, #b9c1d2 32%, #5b6378 46%, #151821 50%, #3a3f52 54%, #9aa3b8 64%, #f4f6fb 76%, #ffffff 82%, #c4cad8 92%, #8a92a6 100%)";

/** Concave four-point glint. */
const Sparkle: React.FC<{ x: number; y: number; r: number; rot?: number; opacity?: number }> = ({ x, y, r, rot = 0, opacity = 1 }) => (
  <g transform={`translate(${x} ${y}) rotate(${rot})`} opacity={opacity}>
    <path
      d={`M0 ${-r} C ${r * 0.08} ${-r * 0.08} ${r * 0.08} ${-r * 0.08} ${r} 0 C ${r * 0.08} ${r * 0.08} ${r * 0.08} ${r * 0.08} 0 ${r} C ${-r * 0.08} ${r * 0.08} ${-r * 0.08} ${r * 0.08} ${-r} 0 C ${-r * 0.08} ${-r * 0.08} ${-r * 0.08} ${-r * 0.08} 0 ${-r} Z`}
      fill="url(#cd-sparkle)"
      filter="url(#cd-glow)"
    />
    <circle r={r * 0.09} fill="#fff" />
  </g>
);

const starburst = (cx: number, cy: number, outer: number, inner: number, points: number) =>
  Array.from({ length: points * 2 }, (_, i) => {
    const a = (Math.PI * i) / points - Math.PI / 2;
    const rr = i % 2 === 0 ? outer : inner;
    return `${(cx + Math.cos(a) * rr).toFixed(1)},${(cy + Math.sin(a) * rr).toFixed(1)}`;
  }).join(" ");

export const ChromeDropPoster: React.FC<ChromeDropPosterProps> = (p) => {
  const brandFont = useBrandFont(p.brandKit?.fonts[0]);
  const display = brandFont ?? DISPLAY;
  const glow = p.brandKit?.colors[0] ?? p.glowColor;
  const glow2 = p.brandKit?.colors[2] ?? p.glowColor2;
  const bg = p.brandKit?.colors[1] ?? p.backgroundColor;
  const ink = p.textColor;

  const lines = p.headline.split("\n").filter(Boolean);
  const longest = Math.max(...lines.map((l) => l.length), 1);
  const size = Math.min(p.headlineSize, (W * 0.9) / (longest * 0.68));
  const lineH = size * 0.9;
  const blockH = lineH * lines.length;
  const headTop = CY - blockH / 2;

  const small: React.CSSProperties = {
    fontFamily: GROTESK,
    fontWeight: 500,
    fontSize: 26,
    letterSpacing: "0.22em",
    textTransform: "uppercase",
    color: ink,
  };

  const textLayer = (extra: React.CSSProperties, key: string) => (
    <div
      key={key}
      style={{
        position: "absolute",
        inset: 0,
        fontFamily: display,
        fontSize: size,
        lineHeight: `${lineH}px`,
        textAlign: "center",
        textTransform: "uppercase",
        letterSpacing: "-0.01em",
        whiteSpace: "pre",
        ...extra,
      }}
    >
      {lines.join("\n")}
    </div>
  );

  // Tiny glints scattered deterministically.
  const dust = Array.from({ length: 26 }, (_, i) => ({
    x: random(`cd-x-${i}`) * W,
    y: 180 + random(`cd-y-${i}`) * 1500,
    r: 3 + random(`cd-r-${i}`) * 7,
    o: 0.35 + random(`cd-o-${i}`) * 0.5,
  }));

  const badgeLines = p.badge.split("\n");

  return (
    <AbsoluteFill style={{ background: bg, overflow: "hidden" }}>
      {/* SVG defs shared by layers */}
      <svg width={0} height={0} style={{ position: "absolute" }}>
        <defs>
          <filter id="cd-bevel" x="-10%" y="-10%" width="120%" height="120%">
            <feGaussianBlur in="SourceAlpha" stdDeviation={size * 0.03} result="blur" />
            <feSpecularLighting in="blur" surfaceScale={size * 0.035} specularConstant={1.15} specularExponent={22} lightingColor="#ffffff" result="spec">
              <fePointLight x={W * 0.25} y={-600} z={700} />
            </feSpecularLighting>
            <feComposite in="spec" in2="SourceAlpha" operator="in" result="specIn" />
            <feComposite in="SourceGraphic" in2="specIn" operator="arithmetic" k1={0} k2={1} k3={0.75} k4={0} />
          </filter>
          <filter id="cd-glow" x="-100%" y="-100%" width="300%" height="300%">
            <feGaussianBlur stdDeviation={3} result="b" />
            <feMerge>
              <feMergeNode in="b" />
              <feMergeNode in="SourceGraphic" />
            </feMerge>
          </filter>
          <radialGradient id="cd-sparkle">
            <stop offset="0%" stopColor="#ffffff" />
            <stop offset="55%" stopColor="#eef0ff" />
            <stop offset="100%" stopColor={glow} />
          </radialGradient>
          <radialGradient id="cd-badge" cx="35%" cy="30%" r="75%">
            <stop offset="0%" stopColor="#ffffff" />
            <stop offset="35%" stopColor="#c9cfdc" />
            <stop offset="55%" stopColor="#5d6478" />
            <stop offset="62%" stopColor="#2a2e3b" />
            <stop offset="80%" stopColor="#b5bccb" />
            <stop offset="100%" stopColor="#f2f4fa" />
          </radialGradient>
          <linearGradient id="cd-ring" x1="0" y1="0" x2="1" y2="0">
            <stop offset="0%" stopColor={glow} stopOpacity={0} />
            <stop offset="45%" stopColor="#ffffff" stopOpacity={0.7} />
            <stop offset="100%" stopColor={glow2} stopOpacity={0} />
          </linearGradient>
        </defs>
      </svg>

      {/* Atmosphere */}
      <AbsoluteFill
        style={{
          background: `radial-gradient(60% 40% at 15% 8%, ${glow}33 0%, transparent 70%), radial-gradient(55% 35% at 95% 95%, ${glow2}2e 0%, transparent 70%)`,
        }}
      />
      {p.image ? (
        <AbsoluteFill style={{ maskImage: "radial-gradient(70% 45% at 50% 47%, #000 30%, transparent 100%)", WebkitMaskImage: "radial-gradient(70% 45% at 50% 47%, #000 30%, transparent 100%)" }}>
          <Img
            src={resolveSrc(p.image)}
            style={{ width: "100%", height: "100%", objectFit: "cover", filter: "grayscale(1) contrast(1.35) brightness(0.8)", opacity: 0.7 }}
          />
          <AbsoluteFill style={{ background: `linear-gradient(135deg, ${glow}, ${glow2})`, mixBlendMode: "color", opacity: 0.55 }} />
        </AbsoluteFill>
      ) : null}
      {/* Holographic orb behind the type */}
      <div
        style={{
          position: "absolute",
          left: W / 2 - 430,
          top: CY - 430,
          width: 860,
          height: 860,
          borderRadius: "50%",
          background: `conic-gradient(from 210deg, ${glow}, #ffb8e6, ${glow2}, #c8ffe9, ${glow})`,
          filter: "blur(110px)",
          opacity: p.image ? 0.35 : 0.55,
        }}
      />

      {/* Orbit rings + sparkles */}
      <svg width={W} height={1920} style={{ position: "absolute", inset: 0 }}>
        <ellipse cx={W / 2} cy={CY} rx={520} ry={150} fill="none" stroke="url(#cd-ring)" strokeWidth={2} transform={`rotate(-14 ${W / 2} ${CY})`} />
        <ellipse cx={W / 2} cy={CY} rx={470} ry={600} fill="none" stroke="url(#cd-ring)" strokeWidth={1.5} transform={`rotate(24 ${W / 2} ${CY})`} opacity={0.6} />
        {dust.map((d, i) => (
          <Sparkle key={i} x={d.x} y={d.y} r={d.r} opacity={d.o} rot={i * 13} />
        ))}
      </svg>

      {/* Top row */}
      <div style={{ position: "absolute", top: 110, left: 72, right: 72, display: "flex", justifyContent: "space-between", alignItems: "center", ...small }}>
        <span>◆ {p.topLeft}</span>
        <span style={{ flex: 1, height: 1, margin: "0 28px", background: `linear-gradient(90deg, transparent, ${ink}88, transparent)` }} />
        <span>{p.topRight}</span>
      </div>

      {/* Chrome headline: rim, outline, beveled chrome, holo sheen */}
      <div style={{ position: "absolute", left: 0, right: 0, top: headTop, height: blockH }}>
        {textLayer(
          {
            color: "transparent",
            WebkitTextStroke: `${size * 0.075}px #0a0b10`,
            filter: `drop-shadow(0 ${size * 0.05}px ${size * 0.08}px rgba(0,0,0,0.7)) drop-shadow(0 0 ${size * 0.18}px ${glow}66)`,
          },
          "shadow",
        )}
        {textLayer({ color: "transparent", WebkitTextStroke: `${size * 0.05}px #c9d0de` }, "rim")}
        {textLayer({ color: "transparent", WebkitTextStroke: `${size * 0.028}px #12141c` }, "outline")}
        {textLayer(
          {
            backgroundImage: CHROME,
            backgroundSize: `100% ${lineH}px`,
            backgroundPosition: `0 ${size * 0.02}px`,
            WebkitBackgroundClip: "text",
            backgroundClip: "text",
            color: "transparent",
            filter: "url(#cd-bevel)",
          },
          "chrome",
        )}
        {textLayer(
          {
            backgroundImage: `linear-gradient(115deg, transparent 20%, ${glow} 38%, #ffc4ec 48%, ${glow2} 60%, transparent 78%)`,
            WebkitBackgroundClip: "text",
            backgroundClip: "text",
            color: "transparent",
            mixBlendMode: "overlay",
            opacity: 0.65,
          },
          "holo",
        )}
      </div>

      {/* Hero glints on the type */}
      <svg width={W} height={1920} style={{ position: "absolute", inset: 0 }}>
        <Sparkle x={W / 2 - size * 1.05} y={headTop + size * 0.12} r={46} />
        <Sparkle x={W / 2 + size * 0.55} y={headTop + blockH - size * 0.18} r={34} rot={8} />
        <Sparkle x={W / 2 + size * 0.95} y={headTop + blockH + 70} r={18} />
        <Sparkle x={140} y={headTop + blockH + 40} r={14} />
      </svg>

      {/* Starburst badge */}
      <div style={{ position: "absolute", left: W - 330, top: headTop - 190, width: 280, height: 280, transform: "rotate(-12deg)" }}>
        <svg width={280} height={280} viewBox="0 0 280 280" style={{ position: "absolute", inset: 0, filter: `drop-shadow(0 14px 24px rgba(0,0,0,0.6)) drop-shadow(0 0 30px ${glow}55)` }}>
          <polygon points={starburst(140, 140, 136, 108, 18)} fill="url(#cd-badge)" stroke="#0b0c12" strokeWidth={4} strokeLinejoin="round" />
          <circle cx={140} cy={140} r={92} fill="none" stroke="#0b0c12" strokeOpacity={0.35} strokeWidth={2} />
        </svg>
        <div
          style={{
            position: "absolute",
            inset: 0,
            display: "flex",
            flexDirection: "column",
            alignItems: "center",
            justifyContent: "center",
            fontFamily: GROTESK,
            fontWeight: 700,
            fontSize: 44,
            lineHeight: 0.95,
            letterSpacing: "-0.01em",
            textTransform: "uppercase",
            color: "#0b0c12",
          }}
        >
          {badgeLines.map((l, i) => (
            <span key={i}>{l}</span>
          ))}
        </div>
      </div>

      {/* Sub pill */}
      <div style={{ position: "absolute", left: 0, right: 0, top: headTop + blockH + 90, display: "flex", justifyContent: "center" }}>
        <div
          style={{
            padding: "22px 44px",
            borderRadius: 999,
            border: "2px solid transparent",
            background: `linear-gradient(${bg}e6, ${bg}e6) padding-box, linear-gradient(90deg, #ffffff, #7d8598, #ffffff, ${glow}, #ffffff) border-box`,
            fontFamily: GROTESK,
            fontWeight: 500,
            fontSize: 36,
            letterSpacing: "0.01em",
            color: ink,
            boxShadow: `0 0 40px ${glow}33`,
          }}
        >
          {p.sub}
        </div>
      </div>

      {/* Footer */}
      <div style={{ position: "absolute", left: 72, right: 72, bottom: 110 }}>
        <div style={{ height: 1, background: `linear-gradient(90deg, ${ink}aa, ${ink}11)`, marginBottom: 40 }} />
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-end" }}>
          <div>
            <div
              style={{
                fontFamily: GROTESK,
                fontWeight: 700,
                fontSize: 150,
                lineHeight: 0.85,
                letterSpacing: "-0.05em",
                backgroundImage: CHROME,
                WebkitBackgroundClip: "text",
                backgroundClip: "text",
                color: "transparent",
                filter: "url(#cd-bevel)",
              }}
            >
              {p.date}
            </div>
            <div style={{ ...small, marginTop: 22 }}>{p.time}</div>
          </div>
          <div style={{ textAlign: "right" }}>
            <div style={{ fontFamily: GROTESK, fontWeight: 700, fontSize: 40, color: "#ffffff", letterSpacing: "-0.01em" }}>{p.handle}</div>
            <div style={{ ...small, marginTop: 14, opacity: 0.7 }}>{p.cta} ↗</div>
          </div>
        </div>
      </div>
    </AbsoluteFill>
  );
};

export default ChromeDropPoster;

Remotion code you can paste anywhere, or install it: npx cutship add chrome-drop-poster

MIT License: use it in any video, personal or commercial. License

More from Cutship

Creator page →