Skip to content
VVVER

Design System / 07.9

Typography

Components for readable prose and code, quotations, fitted display type, and one-shot text animation.

Component reference

Char flip

A display-link accent with two copies of each grapheme in a clipped slot. Hover rolls alternating characters in 380ms; exit returns in 240ms. One complete hidden copy carries the accessible text.

Live specimen

Rendered output

API reference

Inputs, types, and behavior

Inputtext
Typestring
BehaviorBlank text returns null; grapheme segmentation keeps emoji and combining marks intact.
Inputas
Type"h1" | "h2" | "h3" | "p" | "span"
BehaviorDefaults to span. Put group/charflip on a wrapping link for focus parity.
InputclassName
Typestring?
BehaviorMerged last on the rendered element.

Component reference

Code block

A squared, horizontally scrollable source container with optional filename, language, line numbers, and a 44px copy action. Raw source remains the copy value when highlighted HTML supplies visual tokens.

Live specimen

Rendered output

hooks/useProofApproval.tsts
import { useCallback, useState } from "react";

export function useProofApproval(initial = false) {
  const [approved, setApproved] = useState(initial);
  const toggle = useCallback(() => setApproved((value) => !value), []);
  return [approved, toggle] as const;
}
bash
npm install github:wu-hongjun/vvver-design-system#v0.10.1 react-markdown remark-gfm rehype-highlight

API reference

Inputs, types, and behavior

Inputcode / html
Typestring?
Behaviorcode is rendered and copied. html is trusted highlighted inner HTML; pass code with it as the raw copy source.
Inputchildren
TypeReactNode?
BehaviorAlternative content. String children also supply line numbers and the copy value.
Inputfilename / language
Typestring?
BehaviorTrimmed top-bar labels. Blank values are omitted and the language class is sanitized.
InputshowLineNumbers
Typeboolean = false
BehaviorShows a readable, aria-hidden gutter when raw string content is non-empty.
Inputcopyable
Typeboolean = true
BehaviorSuccess is announced politely and its reset timer is cleaned up on unmount.
InputclassName / …rest
Typestring? / div props
BehaviorMerged last and forwarded to the outer container.

Component reference

Decode text

A one-shot terminal entrance that locks graphemes from left to right while unresolved positions cycle through numeric glyphs. It finishes in 900ms by default and resolves immediately under reduced motion.

Live specimen

Rendered output

Archive reference

PLATE 07 / CAFÉ / 印刷

API reference

Inputs, types, and behavior

Inputtext
Typestring
BehaviorBlank text returns null; the accessible copy is never scrambled.
Inputduration
Typenumber = 900
BehaviorDuration, clamped to 0–10000ms. Non-finite input uses 900; zero resolves instantly.
InputclassName
Typestring?
BehaviorMerged last on the outer inline element.

Component reference

Display duet

One statement alternating two treatments at the same inherited size. Voice A is medium uppercase; voice B is regular and natural case, so contrast comes from register rather than a second hierarchy.

Live specimen

Rendered output

Workingdocumentnot spectacle

API reference

Inputs, types, and behavior

Inputlines
Type{ text, voice? }[]
BehaviorBlank lines are ignored; an empty result returns null instead of an empty heading.
Inputvoice
Type"a" | "b"?
BehaviorOmit to alternate by valid-line index. Invalid runtime values use that alternation.
Inputas / className
Type"h1" | "h2" | "h3" | "p" / string?
BehaviorThe wrapper defaults to h1; className is merged last.

Component reference

Inline code

An inline code token using the real monospace stack, secondary paper, a 15% hairline, and square corners. Short identifiers remain intact from the small-screen hinge; long phone-width tokens wrap instead of widening the document.

Live specimen

Rendered output

Pin github:wu-hongjun/vvver-design-system#v0.10.1, import prose.css once, then hand markdownComponents to your parser. The chip sits inline at 0.86em so it rides any body copy.

API reference

Inputs, types, and behavior

Inputchildren
TypeReactNode
BehaviorInline token content. Long tokens may wrap on phones; keep complete commands in CodeBlock so they scroll safely.
InputclassName / …rest
Typestring? / code props
BehaviorMerged last and forwarded to the code element.

Component reference

Letter reveal

Graphemes rise and fade once as the display enters the viewport. Words stay unbroken, whitespace is preserved, and each grapheme rises over 750ms. Typical delays remain perceptible; extreme strings compress only after a 1.2s staging window.

Live specimen

Rendered output

Press proof

API reference

Inputs, types, and behavior

Inputtext
Typestring
BehaviorBlank text returns null; a complete sr-only copy carries the accessible text.
Inputrise
Typestring = "0.6em"
BehaviorStarting translate distance as a CSS length.
Inputdelay / stagger
Typenumber = 0 / 50
BehaviorSanitized within a 1.2s staging window so ordinary display lines keep their specified cadence.
Inputas / className
Type"h1"…"span" / string?
BehaviorThe wrapper defaults to span; className is merged last.

Component reference

Mask reveal

Each word rises from its own clipped wrapper on the display easing. The 1200ms transform uses the display curve’s quick rise and long settle. A 600ms staging bound protects extreme strings without compressing ordinary word cadence; reduced motion is immediate.

Live specimen

Rendered output

Masked display

Function before effect

API reference

Inputs, types, and behavior

Inputtext
Typestring
BehaviorBlank text returns null; preserved whitespace sits outside clipped word wrappers.
Inputdelay / stagger
Typenumber = 0 / 30
BehaviorRequested timing is sanitized and compressed into the 80ms window.
Inputas / className
Type"h1"…"span" / string?
BehaviorThe wrapper defaults to span; className is merged last.

Component reference

Prose

A server-safe long-form wrapper applying the source-shipped .vvver-prose scope. The specimen is parsed by react-markdown with GFM and highlight plugins, routed through the public markdownComponents map, and held to a 68ch reading measure.

Live specimen

Rendered output

Production Notes

The July archive pairs a clothbound proof with the press sheet that corrected its spine. Read the identity guidance before turning production marks into decoration, and record the source in proof.source.

Material Check

Keep the paper edge and uneven impression visible. Remove the simulated fold added in the first comp; the photographed wear is already specific.

Before Release
  • Confirm the proof date against the archive sleeve.
  • Preserve the original crop:
    • Keep the printer’s hand in frame.
    • Retain the registration edge.
Export Order
  1. Scan the corrected proof.
  2. Attach the source record.
  3. Publish the approved plate.

Keep the dated proof and photographed wear. Remove the simulated fold.

Proof Register
PlateSourceState
07-AClothbound dummyApproved
07-BPress correctionRe-scan
07-CRegistration sheetArchived

Source Record
ts
function recordProof(plate: string, source: string) {
  // Production facts stay attached to the artifact.
  const reviewed = new Date("2026-07-18");
  return { plate, reviewed, source };
}

API reference

Inputs, types, and behavior

Inputas
TypeElementType = "article"
BehaviorUse a div when the surrounding page already owns the article landmark.
Inputchildren
TypeReactNode?
BehaviorRendered markdown, MDX, or a supplied tree; Prose ships no parser.
InputclassName / …rest
Typestring? / element props
BehaviorMerged last and forwarded to the selected wrapper.

Supplemental markdown map

markdownComponents sends inline code to InlineCode, fenced code to CodeBlock, anchors to the prose link register, and tables into a scroll wrapper. Images remain valid bare elements inside markdown paragraphs; use an unwrap plugin for true figures.

tsx
import { Prose, markdownComponents } from "vvver-design-system";
import "vvver-design-system/prose.css";

<Prose>
  <ReactMarkdown components={markdownComponents}>
    {markdown}
  </ReactMarkdown>
</Prose>

API reference

Inputs, types, and behavior

InputmarkdownComponents
TypeMarkdownComponents
BehaviorExplicit heading, body, list, quote, media, table, code, and pre mappings; no parser dependency.
InputMarkdownComponents
Typeexported type
BehaviorUse when extending or overriding the map locally.

Component reference

Quote

A semantic blockquote and optional figcaption between 15% hairlines. The serif register is display-only; blank quote content returns no figure, and blank attribution or citation strings are omitted.

Live specimen

Rendered output

Name the source, state, and action.
vvver design and identity
Static is a valid and often preferred state.
vvver motion guidance

API reference

Inputs, types, and behavior

Inputchildren
TypeReactNode
BehaviorQuote content inside blockquote. Null or a blank string returns null.
Inputattribution
TypeReactNode?
BehaviorOptional figcaption in the mono register; a blank string is omitted.
Inputcite
Typestring?
BehaviorTrimmed source URL on blockquote; this is metadata, not a visible link.
Inputserif / className
Typeboolean = false / string?
Behaviorserif opts into the countervoice; className is merged last on figure.

Component reference

Scaled text

A single-line poster title fitted to its container with a top-left transform. ResizeObserver and font readiness trigger refits without animating; the wrapper height follows the transformed line.

Live specimen

Rendered output

Physical record

API reference

Inputs, types, and behavior

Inputchildren
TypeReactNode
BehaviorRendered as one nowrap line. Null or blank string content returns null.
Inputas
Type"div" | "h1" | "h2" | "h3" | "p"
BehaviorDefaults to div. Font-ready work is cancelled safely after unmount.
InputclassName
Typestring?
BehaviorMerged last on the semantic wrapper; override the fluid-display fallback when needed.

Component reference

Split text

A display statement mapped to scroll progress by word, grapheme, or supplied line. Fill mode moves from the readable 60% ink floor to full ink; mask mode translates units behind overflow masks, using transform instead of clip-path.

Live specimen

Rendered output

Word / readable fill

A dated record shows when it was checked.

Grapheme / transform mask

Print, paper, café.

Supplied lines

Source before style Function before effect

API reference

Inputs, types, and behavior

Inputtext / children
Typestring?
Behaviortext takes precedence; string children are an alias. Blank content returns null.
Inputsplit / mode
Type"word" | "line" | "char" / "fill" | "mask"
BehaviorDefaults to word/fill. Invalid runtime values use those defaults; char is grapheme-safe.
Inputfloor
Typenumber = 0.6
BehaviorUnfilled opacity in fill mode, clamped to the readable 0.6–1 range.
Inputoverlap
Typenumber = 1.6
BehaviorConcurrent-unit softness, capped at 100; invalid or non-positive input uses 1.6.
Inputstart / end
Typenumber = 0.85 / 0.35
BehaviorViewport fractions clamped to −2…2; malformed input uses the defaults.
Inputas / className
Type"h1"…"span" / string?
BehaviorThe wrapper defaults to span; className is merged last.

Component reference

Text highlighter

Scroll-scrubbed emphasis with either a transform-scaled hairline or a word lift from 60% to full ink. A live reduced-motion preference pins either mode to its complete state.

Live specimen

Rendered output

Production facts stay attached

Material should come from the subject, not from a decorative fiction layered over it.

API reference

Inputs, types, and behavior

Inputtext
Typestring
BehaviorBlank text returns null; lift mode keeps a complete accessible copy.
Inputmode
Type"underline" | "lift"
BehaviorDefaults to underline. Invalid runtime values use underline.
Inputstart / end
Typenumber = 0.9 / 0.5
BehaviorViewport fractions clamped to −2…2; malformed input uses the defaults.
Inputas / className
Type"h1"…"span" / string?
BehaviorThe wrapper defaults to span; className is merged last.

Component reference

Typed text

A grapheme-safe terminal line with a static-width reserve, so typing and deletion do not push adjacent layout. The server snapshot is the complete first line; after hydration it deletes that draft and types the sequence. Reduced motion keeps the complete first line static.

Live specimen

Rendered output

Single record

PLATE 07-A / REVIEWED

Cycling register

SOURCE / CLOTHBOUND DUMMY

API reference

Inputs, types, and behavior

Inputtext
Typestring | string[]
BehaviorBlank entries are ignored; no valid lines returns null. The first line is the stable accessible copy.
Inputspeed / deleteSpeed
Typenumber = 45 / 24
BehaviorMilliseconds per grapheme, clamped to 16–380; non-finite input uses the default.
Inputpause
Typenumber = 900
BehaviorStatic completed-line hold, clamped to 0–10000ms.
Inputloop
Typeboolean?
BehaviorDefaults true for multiple valid lines and false for one. Explicit true retypes one line.
Inputcaret / className
Typeboolean = true / string?
BehaviorReduced motion stops the blink; className is merged last on the scroll-safe wrapper.