80s Cel Anime 80 年代赛璐璐动画

City Lights, 1987·59s·Lemo-Opuscarby Lemomo

Hand-painted cel animation from the golden age of Japanese OVAs, re-created in code: flat two-tone cels over airbrushed backgrounds, backlit neon, limited-animation timing, played back as a late-80s videotape on a CRT television.

The demo: A courier girl rides through a rain-soaked neon city to deliver a tape before the dawn launch.

Music videosGame trailersNostalgia
Style prompt · STYLE.md

Hand-painted cel animation from the golden age of Japanese OVAs, re-created in code: flat two-tone cels over airbrushed backgrounds, backlit neon, limited-animation timing, played back as a late-80s videotape on a CRT television. References (grammar only): 1980s Japanese OVA and TV cel animation in general (painted-background vs flat-cel contrast, backlit light, held drawings, speed grammar, city-pop openings). Borrow the era's craft, never a specific work's characters, mecha, logos, place names or signature shots.

1. Essence, and what it is not

Four layers, and the contrast between them is the look:

  • Background painting: soft airbrushed gradients, glowing windows, wet reflections; painted once at load (colour + emissive pair), then only slid.
  • Cel (characters, vehicles, props): flat fills, hard-edged shadow and highlight shapes, coloured outlines, never pure black; stepped at 12 or 8 fps.
  • Light: backlit cel (透過光): signs, lamps, title letters glowing through the frame; flares, halation.
  • Playback: videotape on a CRT: chroma bleed, scanlines, grille, phosphor glow, darkened corners, faint noise.

If a frame looks like modern digital anime, one layer is missing. Not moe anime (round eyes, giant irises, hatched blush), not vector clip-art (uniform black lines, gradients in shapes), not a film-print pastiche (no gate weave or scratches: this is tape).

2. Materials & rendering

Cel rendering. Fill, then a hard shadow crescent, then a hard highlight crescent, then the coloured outline. No gradients inside a cel shape (exception: one "harmony" painted still at a peak). Automatic shading: clip to the shape and fill shape − shape shifted toward the light with the shadow colour (even-odd); the same shifted away for the highlight and for a saturated neon rim light (2–4 px). Add hand-placed cast shadows. Outlines ~2–3 px at 1080p, scaled down (0.45–0.8×) in extreme close-ups. Colour models per lighting (色指定): define each character in daylight, derive other sets by multiplying lit / shadow / line separately, plus a backlit silhouette set with a warm rim.

People the 80s way. Construct the head (sphere + jaw): long egg-shaped face, soft-point chin, far eye foreshortened with a cheekbone turn in 3/4. Almond eyes near the vertical middle of the head, a thick upper lash line flicking outward, a tall oval layered iris, two highlights, long thin brows. Nose = a shadow plane + one stroke; one faint blush layer, never hatched. Hair in overlapping locks with sharp uneven tips over a wider dark under-layer, a continuous "angel ring" highlight with a zigzag lower edge. Lines: skin thin warm dark brown, hair dark purple; only hard props near-black. Emotion lives in brows, lid height, iris size, mouth corners and shoulders. Build and approve a model sheet first; draw every shot from the same head function.

Backgrounds. Painted once at load: sky gradients, airbrushed clouds with lit undersides, buildings or landscape with painted light sources, and always a matching emissive plate that slides with the colour plate. Wet ground = a flipped, blurred, streaked copy of the plate darkened with ripple bands. Generic sign words only, never brands. Moving plates get a light horizontal smear (~16 px) against strobing.

Light and lens. Bloom strongly from the emissive canvas, weakly from the colour canvas above ~0.9; tint the widest bloom red-orange (halation). Flares: star-burst, anamorphic streak, hexagonal ghosts through frame centre. Stamp every cel's silhouette in black onto the emissive canvas so glow never bleeds through it.

Videotape + CRT, restrained and deterministic: chroma bleed (sharp luma, horizontally blurred and slightly shifted chroma), fine scanlines anchored to output pixels whose gap shrinks on brights, a faint RGB grille, phosphor glow, darkened corners without curved borders, faint signal noise. Subtitles are composited inside the pass after grading. Two optional accents: a power-on (dot → line → picture) and tracking noise (a few frames of tearing, rolling band, vertical hop). Check moiré on a 720p downscale. Frame: full 16:9 as a theatrical feature (4:3 pillarbox is valid for an OVA feel).

3. Colour logic

  • Painted plates carry gradients and atmosphere; cels are flat, few-colour, saturated. Each time of day gets its own colour model, never a filter over the frame.
  • The protagonist has one accent colour that pops in every lighting set. Line colours are dark versions of their fill.
  • Skin gets its own colour in every set; multiplying daylight skin by a tint turns faces pink under neon.
  • Examples: night city (indigo, violet, neon magenta, cyan, window gold); seaside noon (cobalt, white cumulus, sand, coral); classroom dusk (amber, chalk green, brown wood, purple shadows).

4. Type & subtitles

  • Subtitles live on the tape, composited inside the CRT pass: a semi-condensed sans (e.g. Barlow Semi Condensed 600, ~50–56 px), cream-yellow with a thick dark outline and soft shadow, ~96 px above the bottom; a second speaker may take a second colour and a small boxed tag. Hold ≥ max(1.8 s, speech + 0.6 s); a line yields to the next.
  • Titles: heavy italic Latin in a chrome gradient (sky → white horizon line → violet → pink → gold), dark + neon outlines, optional katakana line (e.g. Dela Gothic One), glowing through the emissive layer, flickering on at 12 fps with a light sweep and a star glint.

5. Motion quality

  • Characters on twos (12 fps); performance beats (blinks, eye openings, lip flaps, gestures) on threes (8 fps). Camera, light sweeps, flares and rain on ones (24 fps); a stepped camera judders.
  • Cycles: hair and cloth as ribbons driven by a travelling sine, 4-drawing cycle (6 when calm); bounce = a 12 fps jitter of a few px.
  • Move light, not drawings: coloured bands sweeping across a held cel (source-atop).
  • Impact frames: 2 frames of an inverted or monochrome silhouette over radial lines, then the result.
  • Hold the peak: a painted still with a slow pan, only cycles moving.
  • Fast blinks (one 8 fps closed drawing); eye openings in three drawings; lip flaps of 3–4 shapes at 8 fps ending on a held expression.

6. Camera grammar

A vocabulary, not a route. Opening and ending come from the topic.

Move What it expresses Can serve
Multiplane crane over a tall plate a world revealed layer by layer arriving; descending into a place; rising above it
Side tracking, 3–4 parallax layers steady momentum a journey; a chase; progress
Rear view into a pseudo-3D canyon speed, pressure ahead a race; a tunnel; a countdown
Held bust with light bands speed or tension without animation a drive; waiting; a decision
Insert with bokeh and a sliding highlight this object matters a letter; a key; a ticket
Extreme close-up on eyes resolve, recognition a choice; a promise
Slow pan across a painted still awe, a held breath a peak; a memory; a landscape
Radial speed lines + one-beat freeze the instant before impact a leap; a collision; a goal
Truck-in through a window or screen entering another world a flashback; a broadcast; a dream
Locked two-shot with lip flaps conversation banter; a confession; an argument
An earlier composition repainted what changed after a storm; years later

Cut on bars. Framing: cels readable against the painted plate; keep the lower ~120 px clear for subtitles. Transitions: cuts, white flashes, impact frames, tracking noise at a tape-related beat; no digital dissolves or wipes.

7. Sound palette

  • Instruments (city pop, synth funk, anime-opening pop): saxophone or synth-brass lead, FM electric piano with a bell transient, slap bass, chorus-y 16th guitar chanks, gated-reverb snare and big toms, drum machine, arpeggiated analog synth, string pad, FM bell sparkle. Extended jazz-pop harmony (maj7, 9ths).
  • Techniques, as options: band-pass the score to cassette/AM when a diegetic source plays, then open it; a brass hit on a title; a drum fill left open for an effect; one beat of true silence before a peak; a semitone lift for a last chorus.
  • Foley (synthesized): engines from an RPM curve, rain, tire hiss, wind, bells, radio squelch, impacts, sparks, cassette clicks, crowd murmur, door buzzers, footsteps on wet pavement; tape accents get their own thunk, whine, hiss.
  • Voice: an English-dub feel, short lines; a second voice through a phone/radio band-pass (~380–2800 Hz). Verify every line with whisper.
  • Mix: limit then compress TTS, voices ~10 dB over ducked music (duck ~9 dB), beds ducked ~3 dB, choruses louder than intros, two-pass loudnorm to −14 LUFS.

8. Native moves

A menu: use the ones your story needs.

  • Small flat hero in a huge painted world. Fits content like: a first day in a big company; a child in a museum hall; a lone researcher at an observatory.
  • Stillness as drama (held close-up or harmony still). Fits content like: an exam result; a goodbye at a gate; an unveiling.
  • Backlit light. Fits content like: a lantern festival; a screen full of code; a lighthouse; stage lights.
  • Speed grammar (speed lines, looping plates, impact frames). Fits content like: a sprint final; a data packet crossing the world; a kitchen rush.
  • Light-band sweep on a held cel. Fits content like: a night train; a scanner reading a page; a heartbeat quickening.
  • A song as an object (tape, radio, jukebox changes the score). Fits content like: a band's origin; a family memory; a call-in show.
  • Tape artefacts as punctuation. Fits content like: found home video; a rewind to the past; an interrupted broadcast.
  • Colour-model change (one place, another hour). Fits content like: a day in a shop; a farm's seasons; before/after a renovation.

9. Pitfalls of the medium

  • White cels bloom pink → bloom from the emissive canvas; weak, high-threshold bloom on colour.
  • Neon bleeds through characters → silhouettes stamped into the emissive canvas.
  • Black holes in highlights → clamp before S-curves.
  • Thick rim light swallows thin shapes → 2–4 px offsets.
  • Hair like tentacles, a face like a paper mask, moe eyes, uniform black lines → the drawing rules in §2.
  • Pink faces under coloured light → skin gets its own colour per set; weaker light sweeps on faces.
  • Front views are the hardest drawing → hide them behind a visor, a windscreen or backlight when you can.
  • Pseudo-3D points behind the camera flip into the sky → clamp z to the near plane.
  • Canvas silently falls back to a serif → document.fonts.load every weight before painting.
  • CRT detail inflates files → noise in the shader, only noise=c0s=2:allf=t in ffmpeg, CRF ≈ 23; loudnorm in two passes with linear=true; don't let a limiter flatten the dynamics.

10. Engine

In demo/: cel.js (path, cel, ribbon, flutter), pal.js (colour models), head80.js (80s head, 3 views × expressions), hands.js, bg.js (painted plates, crane plates, wet reflections), fx.js (rain, speed lines, flares, trails), post.js (WebGL tape + CRT pass: bloom, grade, subtitles, power-on, tracking noise), hud.js, music/score.py (numpy FM/slap/brass synthesis), tools/. ?test=model|close|side draws model sheets, ?raw=1 skips the CRT pass. A minimal new use: a harbour sunset plate with its emissive pair, one cel boat shaded with cel.js, through post.js.

11. Variation space

You decide the structure, the characters, the world, the opening, the ending, the camera path, the pacing and the colour models. All far from our demo:

  • Structures: slice of life in four seasons (one place, four colour models, a small change each time); two-hander dialogue (a locked two-shot comedy that breaks into one fantasy sequence); the mock opening credits (a character roster introduced one by one, each with a pose and a name card).
  • Openings: in the middle of a conversation (lip flaps already moving, no establishing shot); a TV being switched on to an in-world broadcast; a close-up of a drawing hand in a classroom, then cut to the world it draws.
  • Endings: a freeze-frame on a laugh with a "to be continued" card; the tape runs out into blue screen; a slow pan up to a starry sky from a quiet rooftop, no dialogue.

How our demo was made (story, shots, score, end card, build): DEMO.md. Read it after your treatment exists.

Director's notes for the demo film

One example among many. Don't reuse its story, arc, shots, props or timings.

Demo: City Lights, 1987 (59 s) · cel-anime-80s.mp4 · source in demo/

Story & structure

After the rain, a courier nicknamed "Nightbird" rides a white motorbike across a neon city to deliver a pilot's forgotten cassette to the launch pad before a dawn rocket launch. One hero, one goal, one deadline (sunrise).

Arc (59 s): cold open with a deadline → the hero sets off (title hit) → joyful momentum montage → an obstacle (a drawbridge rising) → one decisive move (the jump; the peak freezes) → release into a new light (night becomes dawn) → end card. The song on the tape is the score itself: when the cassette plays aboard, the score becomes diegetic.

How the old guide phrased the adaptation idea for this story (kept as one example, not a rule): turn a topic into a delivery, a race against a deadline or a launch; plant the goal early (the rocket on the horizon), block it in act two, reveal it in the light at the end. Other adaptations it listed: a product launch as a courier racing the product to the stage; a love story as two lights crossing a sleeping city; a history lesson as a pilot flying through eras painted as backgrounds.

Native powers spent: painted city vs flat cel (neon city, wet asphalt, dawn sky), limited animation (held close-ups, the jump as a painted still), backlit light (signs, tail lights, gauges, title), speed grammar (parallax, speed lines, impact frames), the theme song as a plot object (the cassette).

Shots

Beat Camera
Cold open Multiplane crane-down over a tall painted plate (sky → rooftops → neon → street), foreground layers faster; radio dispatch over rain
The object that matters Tight insert on a gloved hand holding the cassette, soft bokeh behind, a highlight sliding over its plastic
Resolve Extreme close-up on the eyes; they open in three 8 fps drawings on the line "Copy. I'll beat the sun."
Title Backlit title card, letters flicker on at 12 fps, a light bar sweeps across, star glint, on the brass hit
Momentum Side tracking with 4 parallax layers + tail-light trail; rear view into a neon canyon (pseudo-3D); held bust with neon light bands; wheel insert through a puddle; a wide elevated-highway shot that plants the goal (the rocket across the bay)
Obstacle First-person approach to the rising drawbridge; glove twisting the throttle and the rev gauge in extreme close-up, cutting faster
Peak Low front view on radial speed lines → one-beat freeze + white flash → impact frame → painted "harmony" still of the airborne bike with a slow pan → impact frame → landing with sparks and camera shake
Release The same side-tracking composition as the night ride, repainted at dawn by the sea with the sky open
Handover Two hands through a fence pass the tape; a finger presses PLAY on the cockpit cassette deck
Ending The rocket lifts off (tilt up, delayed); warm close-up that answers the opening line ("Told you I'd beat the sun."), then the end card

The rider's front view was tucked behind a tinted windscreen so only goggles and hair show, letting the headlight flare carry the shot. Cuts landed on bars (116 BPM, bar = 2.069 s).

Score structure

Original city-pop / synth-funk "anime opening", synthesized in numpy (demo/music/score.py): 116 BPM, E♭ major, maj7/9 chords, the J-pop "royal road" progression (IVM7–V7–iii7–vi7). FM electric piano (DX7-style 1:1 carriers + a 14:1 bell transient), slap bass (thumb + octave pops), gated-reverb snare, synth brass stabs, chorus-y 16th-note guitar chanks, string pad, a singable lead hook, FM bell sparkle, and a key change up a semitone for the last chorus.

Written to the cut: intro under the cold open, a fill bar with space for engine revs, the title on a brass hit, verse under the montage, a pre-chorus build, one beat of true silence before the jump, the chorus on the painted still, an accent on the landing, and the final chord on the end card. Diegetic twist: when the tape plays in the cockpit, the score is band-passed to a cassette sound for one bar, then opens to full range with the key change as the rocket lifts.

Foley: engine from an RPM curve (harmonic saw stack + firing jitter + band-passed exhaust pulses, low-passed when airborne), rain bed + random drops, tire hiss on wet road, wind, bridge bells, radio squelch clicks, impact boom, metal scrape and sparks, cassette clicks, button + motor, rocket ignition and roar.

Voices: an English-dub feel, 8 short lines: the heroine (Kokoro af_bella) and a radio dispatcher (Kokoro am_michael through a band-pass 380–2800 Hz + saturation + squelch). Whisper misheard "Launch is at dawn", so it became "The launch is at dawn". Mix: voices balanced by RMS ~10 dB above the ducked music, music ducked ~9 dB under lines, engine and ambience ducked 3 dB, chorus 4–6 dB louder than the intro, two-pass loudnorm to −14 LUFS.

Palette & props

  • Night: indigo / deep violet / neon magenta / cyan / warm window gold. Dawn: periwinkle / rose / peach / pale gold. The hero's accent: a coral scarf, readable in both.
  • Colour-model multipliers used: night lit ×[.78,.74,1.0], shadow ×[.58,.52,.92]; dawn lit ×[1.04,.9,.84]; a backlit silhouette set (dark purple with an orange rim) for the jump. Skin line ≈ #5a2e2e.
  • Props: white motorbike, cassette labelled "SIDE A · CITY LIGHTS", headset and goggles (near-black, heavier lines), pinch-grip gloves, rev gauge, drawbridge with red warning lights, rocket on a floodlit pad across the bay, cockpit cassette deck with backlit level meters. Signs: BAR, CAFE, 喫茶, ホテル, カラオケ.
  • The heroine, as built in head80.js: eyes at the vertical middle of the head, mouth at the upper third between nose base and chin; iris layered top-dark band → dark upper half → main colour → bright lower crescent, one large and one small highlight; 2–3 separate lashes in the flick; mouth set closed / set / talk / "oh" / pant / smile / open smile with a dark-red interior and a faint lower-lip stroke; profile with a small skull-back, small slightly upturned nose, neck leaning forward. Blinks hold the closed drawing 2–3 frames; brows carry resolve vs exhaustion; shoulders rise when panting; a star glint in the eye highlight on a musical accent.
  • CRT numbers used: chroma blur ~7 px, Cr shift ~2 px; scanlines 3 px period, strength 0.18, gap 1 − a·ph·(1 − 0.6·L); grille ±0.06; phosphor glow 0.35; corners 1 − 0.28·(2u²v² + 0.25(u²+v²)). Moiré check: at 720p the 3 px scanline becomes a clean 2-row alternation; 900p shows a faint 5-row pattern; below 480p it disappears. Film-only artefacts (gate weave, dust, scratches, misregistration) were tried in the treatment and removed: they contradict the tape conceit. The power-on opens the film with a thunk + line whine; tracking noise marks the tape beat with a short hiss/warble.

End card

Darkened final dawn background, the title, the style name "80s Cel Anime", "LemoLab × Claude Opus 5.5", a one-line originality note and credits. The "LemoLab × Claude Opus 5.5" sign-off belongs to this library's demo only; a user's film carries no LemoLab credit and no copy of this card.

Title card as used: "CITY LIGHTS" in heavy italic chrome with シティ・ライツ above (Dela Gothic One), a red "1987" and a spaced-out tagline. Subtitles: Barlow Semi Condensed 600, 54 px, cream-yellow #fff0a0, 9 px dark outline, 96 px above the bottom; radio lines cyan #8ff4ff with a boxed "● BASE" tag; each line up for max(duration + 0.6 s, 1.9 s).

Rights & credits

  • Original score, sound design, animation and all drawings: generated by code in this folder (numpy, Canvas 2D, WebGL). No samples, no stock art.
  • Voices: Kokoro TTS (Apache 2.0), voices af_bella, am_michael.
  • Fonts (SIL Open Font License 1.1, licence files in demo/fonts/): Dela Gothic One (artakana), Kanit (Cadson Demak), Barlow Semi Condensed (Jeremy Tribby).
  • Inspired by 1980s Japanese cel animation; all characters, vehicles, places and the story are original.

Build notes

styles/cel-anime-80s/demo/
  cel.js     path / cel / ribbon / flutter helpers      pal.js   color models (day → night / dawn / backlit)
  rider.js   side-view bike + rider, limbs, wheels      head80.js  80s heroine head: 3 views × expressions, body/collar/scarf
  hands.js   pinch-grip gloves                          bg.js    painted plates (street, skyline, tall crane plates, reflections)
  fx.js      rain, splashes, speed lines, flares, lamps, light trails
  post.js    WebGL videotape + CRT pass (bloom, grade, chroma bleed, subtitles, scanlines, grille, glow, power-on, tracking noise)
  shots.js + scenes1–4.js   one function per shot     story.js  bar-aligned timeline, lines, credits
  hud.js     VHS-style subtitles     main.js  plates, shot dispatch, sound events
  lines.json voices   mix.py   music/score.py (original score)   tools/ (still, sheet, srt, mux)
  1. Treatment → story.js (116 BPM bar grid, shots, lines).
  2. node styles/cel-anime-80s/demo/tools/still.mjs styles/cel-anime-80s/demo --range 0.5:58.5:1 --out /tmp/cs → tools/sheet.py contact sheet → look → fix. ?test=model|close|side renders the model sheet / head close-up / rider; ?raw=1 bypasses the CRT pass; ?nosub=1 hides subtitles.
  3. .venv/bin/python core/tts/tts.py demo/lines.json demo/voices → core/tts/asr_check.py.
  4. .venv/bin/python demo/music/score.py (score + stems + cue times).
  5. node core/render/events.mjs demo → .venv/bin/python demo/mix.py.
  6. node core/render/video.mjs demo --fps 24 --workers 4 --out demo/out/video24.mp4 (1416 frames ≈ 36 s on an M-series Mac).
  7. sh demo/tools/mux.sh demo/out/video24.mp4 demo/mix.wav cel-anime-80s.mp4 24, python demo/tools/srt.py.

Encoding numbers: ffmpeg grain luma 4 + chroma 1 at CRF 22 gave ~32 MB/min; luma 5 + chroma 2 at CRF 18 was 270 MB; with the CRT pass CRF 22 went over 35 MB/min, CRF 23 with luma-only noise 2 lands at ~31 MB. Single-pass loudnorm landed at −13.5 LUFS; two-pass with linear=true lands at −14.0. A hot limiter squashed the chorus to the intro's loudness: normalize to the 99.99th percentile and let only rare peaks hit the limiter.

Pitfalls tied to this demo's props:

  • Bloom threshold on the colour canvas turned the white bike and the jacket pink.
  • The S-curve made a black hole in the headlight (clamp first).
  • A rim offset of 6–8 px turned the thin hair ribbons completely pink.
  • The first hair version looked like tentacles; bang tips over the eyes hid the lash line.
  • The first face was a paper mask: a 3/4 body with a flattened front face (equal eyes, no cheekbone turn, V chin, long thin neck).
  • Night faces went pink from the night tint + magenta rim + pink light sweeps; forehead patches showed between bang locks.
  • In the rear canyon shot, points behind the camera flipped up into the sky.
  • The rocket left the frame: follow it with a delayed tilt and a slower (quadratic) climb.