Type Fossil

A readable word carries layers of fine contours, revises itself, then compresses into a clean typographic imprint

Installation
$ pnpm dlx shadcn@latest add @remocn/type-fossil

Usage

A solid word sits in front of fine offset contours, forming a typographic slice. Earlier versions replace one another with a clean wipe. Every contour carries the same wording as the foreground. After the last revision, the slice's depth compresses, the lettering straightens, and a crisp final imprint remains.

tsx
import { TypeFossil } from "@/components/remocn/type-fossil";
 
export const Scene = () => <TypeFossil />;

All shapes render in one SVG with bounded parallel offsets. The foreground stays opaque. During a revision, complementary clipping regions replace the old text with the new text without a transparent crossfade. No assets, shaders, font downloads, or simulation state are required.

Your revisions

text is the final copy. Separate drafts with | or newlines; up to twelve non-empty drafts are used. Each revision receives a full beat, and the preview automatically adjusts its duration. Empty drafts animate just the final word's contours. Empty final text leaves only the background.

tsx
<TypeFossil
  text="Clarity"
  drafts="What if | Less | Closer"
  layers={20}
  depth={110}
  color="#fffaf0"
  accentColor="#e8ef9b"
  backgroundColor="#32153c"
/>

layers sets contour density. depth sets the slice's total thickness, which remains bounded when the layer count changes. Long copy conservatively shrinks to fit without stretching glyphs. A centered 1280 × 720 SVG scales into other aspect ratios; portrait leaves extra space above and below.

Timing

Default sequence at 30 fps and speed={1}:

FramesMotion
0–16Contour thickness opens up behind the first word
20–28Idea → Maybe
38–46Maybe → Try
56–64Try → Almost
74–82Almost → Again
92–100Again → Closer
110–118Closer → Form
126–174Contours compress and lettering straightens
174–208Finished word holds

Revisions start every 18 reference frames (0.6 seconds at 30 fps), with an 8-frame wipe. Each additional draft adds 18 frames. typeFossilLength is the last moving frame at default props. Use getTypeFossilDuration({ drafts, speed }) for the actual duration including the 34-frame final hold. It returns frames at 30 fps; multiply by fps / 30 and round up for another frame rate.

Props11

PropTypeDefault
text
string"Form"

Final word or short phrase

drafts
string"Idea | Maybe | Try | Almost | Again | Closer"

Earlier versions separated by | or newlines; up to twelve

layers
number16

Contour count, rounded and clamped to 4–24

depth
number100

Slice thickness, clamped to 50–150 reference units

fontSize
number220

Maximum font size; copy shrinks to fit

fontWeight
number | string600

Font weight from 100 to 900

color
string"#302b26"

Solid foreground lettering

accentColor
string"#a800b7"

Contours

backgroundColor
string"#eeeae2"

Stage background; accepts transparent

speed
number1

Playback multiplier; zero or negative freezes the initial pose

className
string—

Class on the full-frame root

  • textstring

    Final word or short phrase

    Default"Form"

  • draftsstring

    Earlier versions separated by | or newlines; up to twelve

    Default"Idea | Maybe | Try | Almost | Again | Closer"

  • layersnumber

    Contour count, rounded and clamped to 4–24

    Default16

  • depthnumber

    Slice thickness, clamped to 50–150 reference units

    Default100

  • fontSizenumber

    Maximum font size; copy shrinks to fit

    Default220

  • fontWeightnumber | string

    Font weight from 100 to 900

    Default600

  • colorstring

    Solid foreground lettering

    Default"#302b26"

  • accentColorstring

    Contours

    Default"#a800b7"

  • backgroundColorstring

    Stage background; accepts transparent

    Default"#eeeae2"

  • speednumber

    Playback multiplier; zero or negative freezes the initial pose

    Default1

  • classNamestring

    Class on the full-frame root