#!/usr/bin/env python3 """Deterministically build the work-derived Season Zero X teaser.""" from __future__ import annotations import math import subprocess import wave from pathlib import Path import numpy as np from PIL import Image, ImageDraw, ImageEnhance, ImageFilter, ImageFont W, H, FPS, RATE, DURATION = 720, 1280, 30, 48_000, 30.0 ROOT = Path(__file__).resolve().parent SOURCE = ROOT / "source" OUT = ROOT / "stackchain-season-zero-work-recut.mp4" TMP_VIDEO = ROOT / ".video.mp4" TMP_AUDIO = ROOT / ".audio.wav" BOLD = "/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf" REG = "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf" COLORS = {"ink": "#070b14", "panel": "#111827", "line": "#334155", "white": "#f8fafc", "muted": "#a9b7cc", "gold": "#ffc857", "cyan": "#5ee7f2", "violet": "#c69cff", "green": "#8ff0a4", "orange": "#ff9c66"} ASSETS = {name: Image.open(SOURCE / filename).convert("RGB") for name, filename in { "drop": "daily-drop-door-phone.png", "cannon": "cannon-scene-04.png", "wizard": "wizard.png", "machine": "machine.png", "creature": "creature.png", "turd": "talking-turd.png", }.items()} def font(size: int, bold: bool = False): return ImageFont.truetype(BOLD if bold else REG, size) def ease(x: float) -> float: x = max(0.0, min(1.0, x)) return x * x * (3 - 2 * x) def fit_crop(image: Image.Image, box: tuple[int, int, int, int], zoom: float = 1.0, pan_y: float = 0.5) -> Image.Image: x0, y0, x1, y1 = box bw, bh = x1-x0, y1-y0 scale = max(bw/image.width, bh/image.height) * zoom rw, rh = max(1, int(image.width*scale)), max(1, int(image.height*scale)) resized = image.resize((rw, rh), Image.Resampling.LANCZOS) left = max(0, (rw-bw)//2) top = max(0, min(rh-bh, int((rh-bh)*pan_y))) return resized.crop((left, top, left+bw, top+bh)) def rounded_image(canvas: Image.Image, image: Image.Image, box: tuple[int, int, int, int], radius: int = 24, zoom: float = 1.0, pan_y: float = 0.5, border: str = COLORS["line"]): crop = fit_crop(image, box, zoom, pan_y) mask = Image.new("L", crop.size, 0) ImageDraw.Draw(mask).rounded_rectangle((0, 0, crop.width-1, crop.height-1), radius, fill=255) canvas.paste(crop, (box[0], box[1]), mask) d = ImageDraw.Draw(canvas) d.rounded_rectangle(box, radius, outline=border, width=3) def text(d: ImageDraw.ImageDraw, xy, value: str, size: int, fill: str = COLORS["white"], bold: bool = False, anchor: str | None = None): d.text(xy, value, font=font(size, bold), fill=fill, anchor=anchor) def centered(d, value: str, y: int, size: int, fill: str = COLORS["white"], bold: bool = False): text(d, (W//2, y), value, size, fill, bold, "ma") def base(t: float) -> Image.Image: y = np.linspace(0, 1, H)[:, None, None] top = np.array((5, 10, 20))[None, None, :] bottom = np.array((22, 15, 40))[None, None, :] grad = top*(1-y) + bottom*y xwave = 5*np.sin(np.linspace(0, 9, W)[None, :, None] + t*.6) arr = np.broadcast_to(grad, (H, W, 3)) + xwave im = Image.fromarray(np.clip(arr, 0, 255).astype(np.uint8), "RGB") d = ImageDraw.Draw(im) for i in range(7): yy = int((t*52 + i*195) % (H+160))-80 d.line((0, yy, W, yy-120), fill=(25, 42, 65), width=2) return im def chrome(d: ImageDraw.ImageDraw, t: float, active: int): d.rectangle((0, 0, W, 76), fill="#080d18") d.line((0, 76, W, 76), fill=COLORS["line"], width=2) text(d, (32, 23), "STACKCHAIN LAB", 25, COLORS["white"], True) text(d, (W-32, 25), "SEASON ZERO", 20, COLORS["gold"], True, "ra") nodes = [(64, "WORK"), (215, "CHALLENGE"), (390, "MUTATE"), (563, "AUDIENCE")] y = 1208 d.line((64, y, 656, y), fill=COLORS["line"], width=5) progress = min(1, max(0, t/DURATION)) d.line((64, y, 64+592*progress, y), fill=COLORS["cyan"], width=5) for i, (x, label) in enumerate(nodes): c = COLORS["gold"] if i == active else (COLORS["cyan"] if i < active else COLORS["line"]) d.ellipse((x-9, y-9, x+9, y+9), fill=c) text(d, (x, y+27), label, 15, c, True, "ma") scan = int((t*155) % (H-160)) + 80 d.rectangle((0, scan, W, scan+2), fill="#5ee7f222") def issue_card(d, box, number, title, owner, state, accent): d.rounded_rectangle(box, 14, fill=COLORS["panel"], outline=accent, width=2) x0, y0, x1, _ = box text(d, (x0+15, y0+13), f"#{number}", 19, accent, True) text(d, (x1-15, y0+15), state.upper(), 16, COLORS["muted"], True, "ra") words = title.split() lines, line = [], "" for word in words: trial = (line+" "+word).strip() if d.textlength(trial, font=font(19, True)) > x1-x0-30: lines.append(line); line = word else: line = trial lines.append(line) for i, ln in enumerate(lines[:2]): text(d, (x0+15, y0+46+i*25), ln, 19, COLORS["white"], True) text(d, (x0+15, y0+104), f"agent:{owner}", 16, accent) def scene_board(im: Image.Image, t: float): d = ImageDraw.Draw(im) local = t centered(d, "THE WORK IS PUBLIC", 112, 35, COLORS["white"], True) centered(d, "A LIVE QUEUE. A REAL HANDOFF.", 158, 21, COLORS["cyan"], True) sway = int(7*math.sin(local*1.8)) d.rounded_rectangle((28+sway, 205, 692+sway, 1015), 24, fill="#0b1220", outline=COLORS["line"], width=3) text(d, (52+sway, 228), "stackchain / stackchain-lab-loop", 20, COLORS["muted"], True) for x, label, c in [(50, "READY", COLORS["cyan"]), (274, "CLAIMED", COLORS["gold"]), (498, "REVIEW", COLORS["green"])]: text(d, (x+sway, 281), label, 17, c, True) issue_card(d, (48+sway, 320, 254+sway, 455), 7, "The Cannon Needs a Pilot", "vincent", "ready", COLORS["violet"]) issue_card(d, (48+sway, 475, 254+sway, 610), 13, "Attack the Cannon Chain", "vincent", "ready", COLORS["cyan"]) issue_card(d, (274+sway, 320, 480+sway, 455), 16, "Build the X teaser", "timmy", "claimed", COLORS["gold"]) issue_card(d, (498+sway, 320, 672+sway, 455), 1, "Prove the Lab Loop", "vincent", "review", COLORS["green"]) d.rounded_rectangle((54+sway, 670, 666+sway, 962), 18, fill="#16112a", outline=COLORS["violet"], width=3) text(d, (78+sway, 694), "EPIC #7 // SEASON ZERO", 21, COLORS["violet"], True) text(d, (78+sway, 744), "THE CANNON NEEDS A PILOT", 28, COLORS["white"], True) text(d, (78+sway, 801), "6-episode character evolution chain", 19, COLORS["muted"]) for i, line in enumerate(("✓ persistent Timmy", "✓ power / scar / cost / receipt", "✓ audience choice advances canon")): text(d, (90+sway, 846+i*33), line, 19, COLORS["green"] if i < 2 else COLORS["gold"], True) text(d, (50, 1060), "TIMMY → VINCENT → HUMAN REVIEW", 24, COLORS["gold"], True) def scene_receipt(im: Image.Image, t: float): d = ImageDraw.Draw(im) local = t-5 centered(d, "CHALLENGED. THEN VERIFIED.", 116, 31, COLORS["white"], True) x = 38 + int(8*math.sin(local*2)) d.rounded_rectangle((x, 205, W-38+x-38, 945), 22, fill="#0c1423", outline=COLORS["cyan"], width=3) text(d, (x+24, 230), "ISSUE #1 / CONTRIBUTION RECEIPT", 19, COLORS["cyan"], True) d.rounded_rectangle((x+22, 278, W-62, 520), 18, fill=COLORS["panel"], outline=COLORS["line"], width=2) text(d, (x+44, 302), "VINCENT", 23, COLORS["violet"], True) text(d, (W-84, 307), "INDEPENDENT PASS", 16, COLORS["muted"], True, "ra") text(d, (x+44, 355), "Fetched PR #4 from Timmy's branch", 20, COLORS["white"]) text(d, (x+44, 397), "8 TESTS PASS", 39, COLORS["green"], True) text(d, (x+44, 452), "Label transition regression verified", 20, COLORS["muted"]) d.rounded_rectangle((x+22, 555, W-62, 804), 18, fill="#17122b", outline=COLORS["violet"], width=2) text(d, (x+44, 580), "DEFINITION OF DONE", 19, COLORS["violet"], True) checks = ("Both agents read assigned tickets", "Both leave verified evidence", "Timmy → Vincent → review", "Credentials remain host-local") for i, line in enumerate(checks): text(d, (x+48, 633+i*40), "✓", 22, COLORS["green"], True) text(d, (x+82, 635+i*40), line, 19, COLORS["white"]) text(d, (x+24, 856), "RECEIPT: ISSUE #1 • PR #4 • 8/8", 21, COLORS["gold"], True) centered(d, "CRITIQUE BECOMES A BUILD INPUT.", 1012, 23, COLORS["gold"], True) centered(d, "NOT A COMMENT. A CONSEQUENCE.", 1055, 19, COLORS["muted"], True) def scene_sources(im: Image.Image, t: float): d = ImageDraw.Draw(im) local = t-10 centered(d, "REAL ARTIFACTS ENTER THE CHAIN", 112, 29, COLORS["white"], True) shift = int(10*math.sin(local*.9)) rounded_image(im, ASSETS["drop"], (35+shift, 205, 350+shift, 930), 22, 1.03+local*.008, .46, COLORS["gold"]) rounded_image(im, ASSETS["cannon"], (370-shift, 205, 685-shift, 930), 22, 1.05+local*.01, .5, COLORS["orange"]) d = ImageDraw.Draw(im) d.rounded_rectangle((48+shift, 835, 337+shift, 913), 12, fill="#070b14dd") text(d, (65+shift, 852), "DAILY DROP", 19, COLORS["gold"], True) text(d, (65+shift, 881), "THE DOOR / VERIFIED", 16, COLORS["white"], True) d.rounded_rectangle((383-shift, 835, 672-shift, 913), 12, fill="#070b14dd") text(d, (400-shift, 852), "CANNON OUTPUT", 19, COLORS["orange"], True) text(d, (400-shift, 881), "SCENE 04 / SOURCE", 16, COLORS["white"], True) # Animated transfer beam unifies the two work artifacts. beam = int(95 + (local % 2.0)/2.0*520) d.line((beam, 965, beam+70, 965), fill=COLORS["cyan"], width=7) d.polygon([(beam+70, 953), (beam+94, 965), (beam+70, 977)], fill=COLORS["cyan"]) centered(d, "SOURCE → PRESSURE → MUTATION", 1025, 23, COLORS["cyan"], True) centered(d, "THE ART CHANGES JOBS. IT ISN'T FILLER.", 1070, 18, COLORS["muted"], True) def scene_mutations(im: Image.Image, t: float): d = ImageDraw.Draw(im) local = t-16 centered(d, "ONE PILOT. FOUR CONSEQUENCES.", 108, 29, COLORS["white"], True) specs = [ ("wizard", "WIZARD", "AMBIGUITY → SPELL", COLORS["violet"]), ("machine", "MACHINE", "REPEATABILITY → EXACT", COLORS["cyan"]), ("creature", "CREATURE", "HUNGER → SIGNAL", COLORS["green"]), ("turd", "TALKING TURD", "RIDICULE → PUNCHLINE", "#ffd18a"), ] boxes = [(35, 190, 350, 610), (370, 190, 685, 610), (35, 650, 350, 1070), (370, 650, 685, 1070)] for i, ((key, name, pressure, color), box) in enumerate(zip(specs, boxes)): reveal = ease((local-i*.55)/1.3) cx = (box[0]+box[2])//2 cy = (box[1]+box[3])//2 bw, bh = box[2]-box[0], box[3]-box[1] sw, sh = max(8, int(bw*reveal)), max(8, int(bh*reveal)) live = (cx-sw//2, cy-sh//2, cx+sw//2, cy+sh//2) rounded_image(im, ASSETS[key], live, 20, 1.0+.025*math.sin(local*1.7+i), .45, color) d = ImageDraw.Draw(im) if reveal > .78: alpha_box = (box[0]+8, box[3]-94, box[2]-8, box[3]-10) d.rounded_rectangle(alpha_box, 12, fill="#070b14e8") text(d, (box[0]+20, box[3]-82), name, 20 if name != "TALKING TURD" else 17, color, True) text(d, (box[0]+20, box[3]-48), pressure, 16, COLORS["white"], True) centered(d, "PLANNED CARDS • EPISODE 01", 1120, 18, COLORS["gold"], True) def scene_gate(im: Image.Image, t: float): d = ImageDraw.Draw(im) local = t-25 for i, color in enumerate((COLORS["violet"], COLORS["cyan"], COLORS["green"], "#ffd18a")): a = local*.8+i*math.pi/2 x, y = W/2+math.cos(a)*245, 390+math.sin(a)*130 r = 50+8*math.sin(local*3+i) d.ellipse((x-r, y-r, x+r, y+r), fill=color, outline=COLORS["white"], width=3) centered(d, "THE AUDIENCE ALTERS CANON", 125, 25, COLORS["gold"], True) centered(d, "WHICH TIMMY", 590, 57, COLORS["white"], True) centered(d, "GETS TO REMEMBER", 675, 49, COLORS["white"], True) centered(d, "THIS?", 765, 76, COLORS["gold"], True) d.rounded_rectangle((55, 892, W-55, 1000), 18, outline=COLORS["cyan"], width=3) centered(d, "WIZARD / MACHINE", 917, 24, COLORS["white"], True) centered(d, "CREATURE / TALKING TURD", 959, 21, COLORS["white"], True) centered(d, "NO POST UNTIL HUMAN APPROVAL", 1072, 19, COLORS["muted"], True) def frame(t: float) -> Image.Image: im = base(t) if t < 5: scene_board(im, t); active = 0 elif t < 10: scene_receipt(im, t); active = 1 elif t < 16: scene_sources(im, t); active = 1 elif t < 25: scene_mutations(im, t); active = 2 else: scene_gate(im, t); active = 3 chrome(ImageDraw.Draw(im), t, active) # Soft entrance/exit only; scene motion remains continuous within each stage. if t < .35: im = ImageEnhance.Brightness(im).enhance(ease(t/.35)) if t > DURATION-.5: im = ImageEnhance.Brightness(im).enhance(max(0, (DURATION-t)/.5)) return im def build_audio(): n = int(DURATION*RATE) audio = np.zeros(n, dtype=np.float64) rng = np.random.default_rng(1608072026) for beat in np.arange(0, DURATION, .5): i = int(beat*RATE); length = min(int(.16*RATE), n-i); x = np.arange(length)/RATE audio[i:i+length] += .42*np.sin(2*np.pi*(74*x-28*x*x))*np.exp(-x*25) for beat in np.arange(.5, DURATION, 1): i = int(beat*RATE); length = min(int(.12*RATE), n-i); x = np.arange(length)/RATE audio[i:i+length] += .12*rng.normal(0, 1, length)*np.exp(-x*34) for beat in np.arange(.25, DURATION, .5): i = int(beat*RATE); length = min(int(.035*RATE), n-i); x = np.arange(length)/RATE audio[i:i+length] += .04*rng.normal(0, 1, length)*np.exp(-x*80) stages = [(0, 5, (110, 165, 220)), (5, 10, (123, 185, 247)), (10, 16, (98, 147, 196)), (16, 25, (131, 196, 262)), (25, 30, (110, 220, 330))] for start, end, chord in stages: i0, i1 = int(start*RATE), int(end*RATE); x = np.arange(i1-i0)/RATE env = np.minimum(1, x*2)*np.minimum(1, (end-start-x)*2) for f in chord: audio[i0:i1] += .035*np.sin(2*np.pi*f*x)*env audio = np.tanh(audio*1.4) pcm = (audio*32767).astype("