SLOPSHOPPER

Money Heist

Money Heist theme for Claude Code: jumpsuit red and Bank of Spain gold, snowfall while Claude works, themed spinner words and a matching status line.

newbandspinnercommandprompttimer
★ 1v1.0.0MITupdated 2026-10-14Manukrish2504/themes/plugins/money-heist
A shopper browsing a rack in a slop shop
Preview · a replayed session in a sandbox
claude · ~/work/app · money-heist
› fix the failing auth test and add an audit log call ⏺ Read(src/auth.ts) ⎿ Read 6 lines ⏺ Update(src/auth.ts) ⎿ Added 2 lines, removed 1 line ⏺ Bash(bun test) ⎿ 3 pass, 1 fail ● Done. refresh now rejects expired claims and logs an audit event. ✻ Worked for 42s · done 4:20 PM › /money-heist ⎿ money-heist: Pick "Money Heist" in /theme first, then run /money-heist again. ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── › ? for shortcuts
README

Film Themes for Claude Code

<!-- count -->50 themes from films and TV series for Claude Code. Each one restyles the whole terminal UI, not just the colours:

LayerWhat changes
ColoursPrompt border, accents, diffs, plan mode, permission dialogs, message backgrounds, even the ultrathink rainbow, all in the film's palette. Pick it in /theme.
AnimationA three-row band above the prompt while Claude works: falling rain, snow, rising embers, twinkles or drifting particles, depending on the film.
WordsThe spinner says Jacking in…, Cooking… or Jumping to hyperspace…, the end-of-turn line says Decoded for 12s, and the hint under the prompt gets a quote.
Status lineOptional: model, folder, git branch, context and rate-limit bars in the film's colours.

Everything except the status line switches on when you pick the theme in /theme, and stays dormant when you pick another one, so you can install several themes side by side.

Install

Inside Claude Code:

/plugin marketplace add Manukrish2504/themes
/plugin install breaking-bad@film-themes

Then:

  1. Run /theme and pick Breaking Bad (the list previews each theme as you move through it).
  2. Optional: run /breaking-bad:statusline to install the matching status line.
  3. Optional: run /breaking-bad to keep the animation on while Claude is idle too. Run it again to turn it off.

Swap breaking-bad for any name in the gallery below. /plugin also lets you browse the whole collection.

Best with: a truecolor terminal (iTerm2, Ghostty, WezTerm, Kitty, Windows Terminal, VS Code), a dark background, and a font with box-drawing and katakana glyphs (most monospace fonts have them). The status line needs jq.

Removing a theme

  • Pick another theme in /theme; the animation and words stop with it.
  • /<name>:statusline with "remove" (or sh its install.sh --remove) restores the status line you had before.
  • /plugin uninstall <name>@film-themes removes the plugin.

Will it break my existing status line?

No. If you already have one (from another tool or your own script), the installer keeps it running in the background, so anything that reads the status line payload still gets every update; only the text on screen is replaced. Removing the theme's status line puts yours back. Only the statusLine key in ~/.claude/settings.json is touched, and the file is backed up to settings.json.bak-film-themes first.

Gallery

<!-- gallery:start --> <table> <tr><td width="50%" valign="top" id="arcane"><img src="previews/arcane.svg" alt="Arcane theme preview" width="100%"><br><b>Arcane</b> · series, 2021<br><code>/plugin install arcane@film-themes</code></td><td width="50%" valign="top" id="avatar"><img src="previews/avatar.svg" alt="Avatar theme preview" width="100%"><br><b>Avatar</b> · film, 2009<br><code>/plugin install avatar@film-themes</code></td></tr> <tr><td width="50%" valign="top" id="avengers"><img src="previews/avengers.svg" alt="Avengers: Endgame theme preview" width="100%"><br><b>Avengers: Endgame</b> · film, 2019<br><code>/plugin install avengers@film-themes</code></td><td width="50%" valign="top" id="back-to-the-future"><img src="previews/back-to-the-future.svg" alt="Back to the Future theme preview" width="100%"><br><b>Back to the Future</b> · film, 1985<br><code>/plugin install back-to-the-future@film-themes</code></td></tr> <tr><td width="50%" valign="top" id="barbie"><img src="previews/barbie.svg" alt="Barbie theme preview" width="100%"><br><b>Barbie</b> · film, 2023<br><code>/plugin install barbie@film-themes</code></td><td width="50%" valign="top" id="blade-runner"><img src="previews/blade-runner.svg" alt="Blade Runner 2049 theme preview" width="100%"><br><b>Blade Runner 2049</b> · film, 2017<br><code>/plugin install blade-runner@film-themes</code></td></tr> <tr><td width="50%" valign="top" id="breaking-bad"><img src="previews/breaking-bad.svg" alt="Breaking Bad theme preview" width="100%"><br><b>Breaking Bad</b> · series, 2008<br><code>/plugin install breaking-bad@film-themes</code></td><td width="50%" valign="top" id="dark-knight"><img src="previews/dark-knight.svg" alt="The Dark Knight theme preview" width="100%"><br><b>The Dark Knight</b> · film, 2008<br><code>/plugin install dark-knight@film-themes</code></td></tr> <tr><td width="50%" valign="top" id="dune"><img src="previews/dune.svg" alt="Dune theme preview" width="100%"><br><b>Dune</b> · film, 2021<br><code>/plugin install dune@film-themes</code></td><td width="50%" valign="top" id="fight-club"><img src="previews/fight-club.svg" alt="Fight Club theme preview" width="100%"><br><b>Fight Club</b> · film, 1999<br><code>/plugin install fight-club@film-themes</code></td></tr> <tr><td width="50%" valign="top" id="friends"><img src="previews/friends.svg" alt="Friends theme preview" width="100%"><br><b>Friends</b> · series, 1994<br><code>/plugin install friends@film-themes</code></td><td width="50%" valign="top" id="frozen"><img src="previews/frozen.svg" alt="Frozen theme preview" width="100%"><br><b>Frozen</b> · film, 2013<br><code>/plugin install frozen@film-themes</code></td></tr> <tr><td width="50%" valign="top" id="game-of-thrones"><img src="previews/game-of-thrones.svg" alt="Game of Thrones theme preview" width="100%"><br><b>Game of Thrones</b> · series, 2011<br><code>/plugin install game-of-thrones@film-themes</code></td><td width="50%" valign="top" id="ghostbusters"><img src="previews/ghostbusters.svg" alt="Ghostbusters theme preview" width="100%"><br><b>Ghostbusters</b> · film, 1984<br><code>/plugin install ghostbusters@film-themes</code></td></tr> <tr><td width="50%" valign="top" id="godfather"><img src="previews/godfather.svg" alt="The Godfather theme preview" width="100%"><br><b>The Godfather</b> · film, 1972<br><code>/plugin install godfather@film-themes</code></td><td width="50%" valign="top" id="harry-potter"><img src="previews/harry-potter.svg" alt="Harry Potter theme preview" width="100%"><br><b>Harry Potter</b> · film, 2001<br><code>/plugin install harry-potter@film-themes</code></td></tr> <tr><td width="50%" valign="top" id="inception"><img src="previews/inception.svg" alt="Inception theme preview" width="100%"><br><b>Inception</b> · film, 2010<br><code>/plugin install inception@film-themes</code></td><td width="50%" valign="top" id="interstellar"><img src="previews/interstellar.svg" alt="Interstellar theme preview" width="100%"><br><b>Interstellar</b> · film, 2014<br><code>/plugin install interstellar@film-themes</code></td></tr> <tr><td width="50%" valign="top" id="iron-man"><img src="previews/iron-man.svg" alt="Iron Man theme preview" width="100%"><br><b>Iron Man</b> · film, 2008<br><code>/plugin install iron-man@film-themes</code></td><td width="50%" valign="top" id="jaws"><img src="previews/jaws.svg" alt="Jaws theme preview" width="100%"><br><b>Jaws</b> · film, 1975<br><code>/plugin install jaws@film-themes</code></td></tr> <tr><td width="50%" valign="top" id="john-wick"><img src="previews/john-wick.svg" alt="John Wick theme preview" width="100%"><br><b>John Wick</b> · film, 2014<br><code>/plugin install john-wick@film-themes</code></td><td width="50%" valign="top" id="joker"><img src="previews/joker.svg" alt="Joker theme preview" width="100%"><br><b>Joker</b> · film, 2019<br><code>/plugin install joker@film-themes</code></td></tr> <tr><td width="50%" valign="top" id="jurassic-park"><img src="previews/jurassic-park.svg" alt="Jurassic Park theme preview" width="100%"><br><b>Jurassic Park</b> · film, 1993<br><code>/plugin install jurassic-park@film-themes</code></td><td width="50%" valign="top" id="kill-bill"><img src="previews/kill-bill.svg" alt="Kill Bill theme preview" width="100%"><br><b>Kill Bill</b> · film, 2003<br><code>/plugin install kill-bill@film-themes</code></td></tr> <tr><td width="50%" valign="top" id="lion-king"><img src="previews/lion-king.svg" alt="The Lion King theme preview" width="100%"><br><b>The Lion King</b> · film, 1994<br><code>/plugin install lion-king@film-themes</code></td><td width="50%" valign="top" id="lord-of-the-rings"><img src="previews/lord-of-the-rings.svg" alt="The Lord of the Rings theme preview" width="100%"><br><b>The Lord of the Rings</b> · film, 2001<br><code>/plugin install lord-of-the-rings@film-themes</code></td></tr> <tr><td width="50%" valign="top" id="mad-max"><img src="previews/mad-max.svg" alt="Mad Max: Fury Road theme preview" width="100%"><br><b>Mad Max: Fury Road</b> · film, 2015<br><code>/plugin install mad-max@film-themes</code></td><td width="50%" valign="top" id="mandalorian"><img src="previews/mandalorian.svg" alt="The Mandalorian theme preview" width="100%"><br><b>The Mandalorian</b> · series, 2019<br><code>/plugin install mandalorian@film-themes</code></td></tr> <tr><td width="50%" valign="top" id="matrix"><img src="previews/matrix.svg" alt="The Matrix theme preview" width="100%"><br><b>The Matrix</b> · film, 1999<br><code>/plugin install matrix@film-themes</code></td><td width="50%" valign="top" id="money-heist"><img src="previews/money-heist.svg" alt="Money Heist theme preview" width="100%"><br><b>Money Heist</b> · series, 2017<br><code>/plugin install money-heist@film-themes</code></td></tr> <tr><td width="50%" valign="top" id="mr-robot"><img src="previews/mr-robot.svg" alt="Mr. Robot theme preview" width="100%"><br><b>Mr. Robot</b> · series, 2015<br><code>/plugin install mr-robot@film-themes</code></td><td width="50%" valign="top" id="oppenheimer"><img src="previews/oppenheimer.svg" alt="Oppenheimer theme preview" width="100%"><br><b>Oppenheimer</b> · film, 2023<br><code>/plugin install oppenheimer@film-themes</code></td></tr> <tr><td width="50%" valign="top" id="peaky-blinders"><img src="previews/peaky-blinders.svg" alt="Peaky Blinders theme preview" width="100%"><br><b>Peaky Blinders</b> · series, 2013<br><code>/plugin install peaky-blinders@film-themes</code></td><td width="50%" valign="top" id="pulp-fiction"><img src="previews/pulp-fiction.svg" alt="Pulp Fiction theme preview" width="100%"><br><b>Pulp Fiction</b> · film, 1994<br><code>/plugin install pulp-fiction@film-themes</code></td></tr> <tr><td width="50%" valign="top" id="rick-and-morty"><img src="previews/rick-and-morty.svg" alt="Rick and Morty theme preview" width="100%"><br><b>Rick and Morty</b> · series, 2013<br><code>/plugin install rick-and-morty@film-themes</code></td><td width="50%" valign="top" id="severance"><img src="previews/severance.svg" alt="Severance theme preview" width="100%"><br><b>Severance</b> · series, 2022<br><code>/plugin install severance@film-themes</code></td></tr> <tr><td width="50%" valign="top" id="silicon-valley"><img src="previews/silicon-valley.svg" alt="Silicon Valley theme preview" width="100%"><br><b>Silicon Valley</b> · series, 2014<br><code>/plugin install silicon-valley@film-themes</code></td><td width="50%" valign="top" id="spider-verse"><img src="previews/spider-verse.svg" alt="Spider-Man: Into the Spider-Verse theme preview" width="100%"><br><b>Spider-Man: Into the Spider-Verse</b> · film, 2018<br><code>/plugin install spider-verse@film-themes</code></td></tr> <tr><td width="50%" valign="top" id="spirited-away"><img src="previews/spirited-away.svg" alt="Spirited Away theme preview" width="100%"><br><b>Spirited Away</b> · film, 2001<br><code>/plugin install spirited-away@film-themes</code></td><td width="50%" valign="top" id="squid-game"><img src="previews/squid-game.svg" alt="Squid Game theme preview" width="100%"><br><b>Squid Game</b> · series, 2021<br><code>/plugin install squid-game@film-themes</code></td></tr> <tr><td width="50%" valign="top" id="star-wars"><img src="previews/star-wars.svg" alt="Star Wars theme preview" width="100%"><br><b>Star Wars</b> · film, 1977<br><code>/plugin install star-wars@film-themes</code></td><td width="50%" valign="top" id="stranger-things"><img src="previews/stranger-things.svg" alt="Stranger Things theme preview" width="100%"><br><b>Stranger Things</b> · series, 2016<br><code>/plugin install stranger-things@film-themes</code></td></tr> <tr><td width="50%" valign="top" id="the-last-of-us"><img src="previews/the-last-of-us.svg" alt="The Last of Us theme preview" width="100%"><br><b>The Last of Us</b> · series, 2023<br><code>/plugin install the-last-of-us@film-themes</code></td><td width="50%" valign="top" id="the-office"><img src="previews/the-office.svg" alt="The Office theme preview" width="100%"><br><b>The Office</b> · series, 2005<br><code>/plugin install the-office@film-themes</code></td></tr> <tr><td width="50%" valign="top" id="the-simpsons"><img src="previews/the-simpsons.svg" alt="The Simpsons theme preview" width="100%"><br><b>The Simpsons</b> · series, 1989<br><code>/plugin install the-simpsons@film-themes</code></td><td width="50%" valign="top" id="titanic"><img src="previews/titanic.svg" alt="Titanic theme preview" width="100%"><br><b>Titanic</b> · film, 1997<br><code>/plugin install titanic@film-themes</code></td></tr> <tr><td width="50%" valign="top" id="top-gun"><img src="previews/top-gun.svg" alt="Top Gun: Maverick theme preview" width="100%"><br><b>Top Gun: Maverick</b> · film, 2022<br><code>/plugin install top-gun@film-themes</code></td><td width="50%" valign="top" id="toy-story"><img src="previews/toy-story.svg" alt="Toy Story theme preview" width="100%"><br><b>Toy Story</b> · film, 1995<br><code>/plugin install toy-story@film-themes</code></td></tr> <tr><td width="50%" valign="top" id="tron"><img src="previews/tron.svg" alt="Tron: Legacy theme preview" width="100%"><br><b>Tron: Legacy</b> · film, 2010<br><code>/plugin install tron@film-themes</code></td><td width="50%" valign="top" id="wednesday"><img src="previews/wednesday.svg" alt="Wednesday theme preview" width="100%"><br><b>Wednesday</b> · series, 2022<br><code>/plugin install wednesday@film-themes</code></td></tr> </table> <!-- gallery:end -->

How it works

films/<name>.json      the source: 10 colours, spinner words, end-of-turn words, a hint, an animation
engine/                shared by every theme
  register.tsx         the mod: spinner and end-of-turn words, prompt hint, animation band, /<name> command
  statusline.sh        status line template
  install.sh           status line installer (keeps any existing status line running)
  SKILL.md             the /<name>:statusline skill
scripts/build.mjs      generates plugins/, previews/, the marketplace and this README's gallery
plugins/<name>/        one installable plugin per film (generated)

The build derives the full theme (about 50 colour tokens) from the ten palette colours, and refuses to build a theme whose text, accents or status colours do not have enough contrast against both its own background and a typical dark terminal.

The mod reads which theme is active and stays out of the way unless it is its own, so installing several films is safe. The animation runs only while Claude is working (or when you toggle it on), at about nine frames a second, three rows tall.

Add a film

  1. Copy a file in films/, rename it to the new slug (lowercase, dashes), and change its colours, words and animation:
  2. palette: bg is the background the theme is designed for; text, accent, accent2, muted, subtle, border, success, warning, error.
  3. fx.kind: rain, snow, rise, twinkle or drift. fx.colors go from brightest to dimmest. fx.glyphs must be single-width characters (no emoji).
  4. Run node scripts/build.mjs (Node 18+, no dependencies). It prints any contrast problems.
  5. Check it with claude plugin validate plugins/<slug> and try it with claude --plugin-dir plugins/<slug>.
  6. Open a pull request with the film file and the regenerated output.

Disclaimer

This is an unofficial, fan-made project. It is not affiliated with, endorsed by or sponsored by any studio, network or rights holder. Film and series titles, character names and catchphrases belong to their respective owners and are used here only to describe and reference the works that inspired each colour scheme. No logos, artwork, footage or other copyrighted assets are included.

License

MIT

Source 2 files
hooks/register.tsx 170 lines
1import type { ConfigRow, Register } from 'claude-code'
2import { film } from './film'
3
4// Shared by every film plugin: scripts/build.mjs copies this file next to each plugin's film.ts.
5// Everything here stays dormant unless that film's theme is the one picked in /theme.
6
7export type Fx = {
8  kind: 'rain' | 'snow' | 'rise' | 'twinkle' | 'drift'
9  glyphs: string
10  colors: string[] // brightest first
11  density: number // share of the band's cells lit at once
12}
13export type Film = { slug: string; title: string; verbs: string[]; done: string[]; hint: string; fx: Fx }
14
15const THEME = `custom:${film.slug}:${film.slug}`
16const ROWS = 3
17const TICK_MS = 110
18
19type Particle = { x: number; y: number; dx: number; dy: number; trail: number; age: number; life: number; tone: number; g: string }
20export type Run = { tone: number; text: string } // tone -1 is blank
21
22const rand = (n: number) => Math.floor(Math.random() * n)
23const pick = <T,>(xs: readonly T[]): T => xs[rand(xs.length)]!
24
25// A particle field the size of the band. Each kind is a spawn rule; a particle moves by (dx, dy)
26// per tick, drags `trail` dimmer cells behind it, and twinkles fade in and out over their life.
27export const createFx = (fx: Fx) => {
28  const glyphs = [...fx.glyphs]
29  const last = fx.colors.length - 1
30  let ps: Particle[] = []
31  let width = 0
32
33  const spawn = (): Particle => {
34    const p = { age: 0, life: Infinity, trail: 0, tone: 0, dx: 0, dy: 0, g: pick(glyphs) }
35    const drift = (Math.random() - 0.5) * 0.3
36    switch (fx.kind) {
37      case 'rain': return { ...p, x: rand(width), y: -rand(6), dy: 1, trail: last }
38      case 'snow': return { ...p, x: rand(width), y: 0, dx: drift, dy: 0.2 + Math.random() * 0.25, tone: rand(last + 1) }
39      case 'rise': return { ...p, x: rand(width), y: ROWS - 1, dx: drift, dy: -(0.2 + Math.random() * 0.3), tone: rand(last + 1) }
40      case 'drift': return { ...p, x: 0, y: rand(ROWS), dx: 0.8 + Math.random() * 1.6, trail: Math.min(3, last) }
41      case 'twinkle': return { ...p, x: rand(width), y: rand(ROWS), life: 6 + rand(10) }
42    }
43  }
44
45  const alive = (p: Particle) =>
46    p.age < p.life &&
47    p.x - (p.dx > 0 ? p.trail : 0) < width && p.x > -1 &&
48    p.y - (p.dy > 0 ? p.trail : 0) < ROWS && p.y > -7 && !(p.dy < 0 && p.y < -0.5)
49
50  const step = (columns: number) => {
51    width = columns
52    for (const p of ps) { p.x += p.dx; p.y += p.dy; p.age += 1 }
53    ps = ps.filter(alive)
54    const want = Math.round(fx.density * width * ROWS)
55    for (let n = Math.min(want - ps.length, Math.ceil(want / 6) + 1); n > 0; n--) ps.push(spawn())
56  }
57
58  const frame = (): Run[][] => {
59    const grid: ({ tone: number; g: string } | undefined)[][] = Array.from({ length: ROWS }, () => Array(width).fill(undefined))
60    const put = (x: number, y: number, tone: number, g: string) => {
61      const cx = Math.round(x), cy = Math.round(y)
62      const row = grid[cy]
63      if (!row || cx < 0 || cx >= width) return
64      if (!row[cx] || tone < row[cx]!.tone) row[cx] = { tone, g }
65    }
66    const glyph = (p: Particle) => (fx.kind === 'rain' ? pick(glyphs) : p.g) // rain flickers
67    for (const p of ps) {
68      const tone = fx.kind === 'twinkle' ? Math.round(Math.abs(1 - (2 * p.age) / p.life) * last) : p.tone
69      put(p.x, p.y, tone, glyph(p))
70      for (let k = 1; k <= p.trail; k++) put(p.x - k * Math.sign(p.dx), p.y - k * Math.sign(p.dy), Math.min(last, tone + k), glyph(p))
71    }
72    return grid.map(row => {
73      const runs: Run[] = []
74      for (const cell of row) {
75        const tone = cell?.tone ?? -1
76        const ch = cell?.g ?? ' '
77        const prev = runs[runs.length - 1]
78        if (prev?.tone === tone) prev.text += ch
79        else runs.push({ tone, text: ch })
80      }
81      return runs
82    })
83  }
84
85  return { step, frame, width: () => width }
86}
87
88const isOurs = (rows: readonly ConfigRow[]) => rows.find(row => row.key === 'theme')?.value === THEME
89
90export const register: Register = on => {
91  const fx = createFx(film.fx)
92  let active: boolean | undefined // is this film's theme the one picked in /theme
93  let ambient = false // /<slug> keeps the animation on while Claude is idle
94  let verb: string | undefined
95  let columns = 80
96  let timer: { cancel: () => void } | undefined
97
98  on('session.start', async ($, e, next) => {
99    await $.command.register({ name: film.slug, description: `${film.title} theme: toggle its animation while Claude is idle` })
100    active = isOurs(await $.config.list())
101    return next(e)
102  })
103
104  // /theme can change between turns; re-read it once per prompt, and on every change made through /config.
105  on('prompt.submit', async ($, e, next) => {
106    verb = pick(film.verbs)
107    try { active = isOurs(await $.config.list()) } catch { /* keep the last answer */ }
108    return next(e)
109  }).catch(($, e, next) => next(e)) // a theme never stands between you and your prompt
110
111  on('config.set', { key: 'theme' }, async ($, e, next) => {
112    const result = await next(e)
113    if (!result.deny) active = result.value === THEME
114    $.ui.invalidate('ui.render')
115    return result
116  }).catch(($, e, next) => next(e))
117
118  on('command.run', { command: film.slug }, async $ => {
119    active ??= isOurs(await $.config.list())
120    if (!active) return { text: `Pick "${film.title}" in /theme first, then run /${film.slug} again.` }
121    ambient = !ambient
122    $.ui.invalidate('ui.render')
123    return { text: ambient ? `${film.title}: animation stays on while idle.` : `${film.title}: animation only while Claude works.` }
124  }).catch(($, e, next) => next(e))
125
126  on('ui.render', { component: 'Spinner' }, async ($, e, next) => {
127    active ??= isOurs(await $.config.list())
128    return active ? next({ ...e, props: { ...e.props, word: (verb ??= pick(film.verbs)) } }) : next(e)
129  })
130
131  on('ui.render', { component: 'TurnDuration' }, async ($, e, next) => {
132    active ??= isOurs(await $.config.list())
133    return active ? next({ ...e, props: { ...e.props, word: film.done[e.props.durationMs % film.done.length]! } }) : next(e)
134  })
135
136  on('ui.render', { component: 'PromptHint' }, async ($, e, next) => {
137    active ??= isOurs(await $.config.list())
138    const quiet = !active || e.props.isWorking || e.props.isDraft
139    return quiet ? next(e) : next({ ...e, props: { ...e.props, tail: `· ${film.hint}` } })
140  })
141
142  on('ui.render', { component: 'AbovePrompt' }, async ($, e, next) => {
143    active ??= isOurs(await $.config.list())
144    if (!active || !(e.props.isWorking || ambient) || e.props.hasSurvey) {
145      timer?.cancel()
146      timer = undefined
147      return next(e)
148    }
149    columns = e.props.bodyColumns
150    if (fx.width() !== columns) for (let i = 0; i < 30; i++) fx.step(columns) // first frame and resizes start mid-motion
151    timer ??= $.clock.every(TICK_MS, () => {
152      fx.step(columns)
153      $.ui.invalidate('ui.render')
154    })
155
156    const { Box, Text } = $.ui.resolve(e)
157    const colors = film.fx.colors
158    return (
159      <Box flexDirection="column">
160        {fx.frame().map(runs => (
161          <Text wrap="truncate">
162            {runs.map(run =>
163              run.tone < 0 ? run.text : <Text color={colors[run.tone]} weight={run.tone === 0 ? 'bold' : 'regular'}>{run.text}</Text>)}
164          </Text>
165        ))}
166      </Box>
167    )
168  })
169}
170
hooks/film.ts 39 lines
1// Generated from films/money-heist.json by scripts/build.mjs: edit that file, then rebuild.
2import type { Film } from './register'
3
4export const film: Film = {
5  "slug": "money-heist",
6  "title": "Money Heist",
7  "verbs": [
8    "Following the Professor's plan",
9    "Printing money",
10    "Melting the gold",
11    "Singing Bella Ciao",
12    "Wearing the Dalí mask",
13    "Digging the tunnel",
14    "Calling the inspector",
15    "Breaking into the Royal Mint"
16  ],
17  "done": [
18    "Printed",
19    "Melted",
20    "Escaped",
21    "Planned",
22    "Pulled off",
23    "Executed"
24  ],
25  "hint": "bella ciao",
26  "fx": {
27    "kind": "snow",
28    "glyphs": "€$¤",
29    "colors": [
30      "#eaffea",
31      "#b3e6b3",
32      "#73b373",
33      "#3d733d",
34      "#1a331a"
35    ],
36    "density": 0.04
37  }
38}
39