Paper

A printed document on screen: a contract, an incident report, a ticket or a certificate. A white sheet in a serif with typed-in values, laid out at one design width and scaled as a whole to the room it gets, so it reads as the paper it stands for rather than as one more card of the app around it.

NORTHWIND FREIGHT CO · EST. 1987 ·

Employment Agreement

Northwind Freight Co.

State of California

Fixed-term employment · Form HR-104

Contract no.
NW-2026-0417
Status
Pending

Parties

Employer
Northwind Freight Co.
Tax ID
94-3187220
Represented by
Maya Chen
Employee
Daniel Ortega Ruiz
Date of birth
03/14/1994
ID number
D4471209

Position

Job title
Warehouse Operations Lead
Start date
11/02/2026
Base salary
$58,400 / year

Terms

1. The Employee reports to the Operations Manager at the Oakland distribution center and performs the duties set out in Annex A. 2. The first 90 days are a probationary period, during which either party may end this agreement with one week's written notice. 3. Salary is paid biweekly by direct deposit. Hours worked beyond 40 in a week are paid at one and a half times the hourly rate.
For the employer
Maya Chen, HR Director10/04/2026
Employee
Daniel Ortega Ruiz
Form HR-104 · Rev. 03/2026Page 1 of 1

Installation#

# One-time setup (tokens + lib helpers)npx koalaui-cli@latest init# Add this component (its dependencies come along)npx koalaui-cli@latest add paper

Usage#

usage.tsxTSX
import {  Paper,  PaperField,  PaperHeader,  PaperHeading,  PaperRow,  PaperSection,  PaperTitle,} from "@/components/ui/paper"export function Example() {  return (    <Paper>      <PaperHeader>        <PaperHeading>          <PaperTitle>Delivery Note</PaperTitle>        </PaperHeading>      </PaperHeader>      <PaperSection>Consignee</PaperSection>      <PaperRow>        <PaperField label="Name" grow={2}>Priya Raman</PaperField>        <PaperField label="Packages">3</PaperField>      </PaperRow>    </Paper>  )}

Anatomy#

Every part is optional but the sheet. A ticket can be a heading and three rows; a contract uses the lot. Parts stack in the order you write them, each ruled off the next.

import {  Paper,  PaperBox,  PaperCaption,  PaperCheckItem,  PaperChecklist,  PaperField,  PaperFooter,  PaperHeader,  PaperHeaderAside,  PaperHeading,  PaperNote,  PaperRow,  PaperSeal,  PaperSection,  PaperSignature,  PaperSignatures,  PaperSubtitle,  PaperTable,  PaperTableCell,  PaperTableHead,  PaperText,  PaperTitle,} from "@/components/ui/paper"<Paper>  {/* The letterhead: a seal, the centered heading, an aside of boxes */}  <PaperHeader>    <PaperSeal>{/* an img or an svg */}</PaperSeal>    <PaperHeading>      <PaperTitle />      <PaperSubtitle />      <PaperCaption />    </PaperHeading>    <PaperHeaderAside>      <PaperBox label="Number" />    </PaperHeaderAside>  </PaperHeader>  {/* The body: bands, rows of fields, copy, tables, checklists */}  <PaperSection />  <PaperRow>    <PaperField label="Label" grow={2} />  </PaperRow>  <PaperText />  <PaperTable>    <PaperTableHead />    <PaperTableCell />  </PaperTable>  <PaperNote />  <PaperChecklist>    <PaperCheckItem checked />  </PaperChecklist>  {/* Signature lines, side by side, and the small print */}  <PaperSignatures>    <PaperSignature label="Signature" name="Name" date="Date" />  </PaperSignatures>  <PaperFooter /></Paper>

Fit#

A document is not responsive. The sheet is laid out at one design width, width in em (52 by default, 832px at a 16px root), and with fit it scales as a whole to the width it is given: the title stays on one line, a label never breaks in two and the copy keeps its line breaks, at any size. The scale is the sheet's own font size, and every length inside is in em, so the page is laid out again for real rather than zoomed. It never grows past its design size: in a wider column it sits centered.

Parking Citation

City of Bayview

Plate
8KTR204
State
CA
Fine
$63.00
Violation
Expired meter, section 22.2.04
Location
Harbor Way at 3rd St
Issued
10/04 14:52
No. 448120Pay within 21 days
A 240px column

Parking Citation

City of Bayview

Plate
8KTR204
State
CA
Fine
$63.00
Violation
Expired meter, section 22.2.04
Location
Harbor Way at 3rd St
Issued
10/04 14:52
No. 448120Pay within 21 days
A wider column

fit={false} keeps the design width whatever the room, and the frame decides what happens to the overflow: here it scrolls sideways. frameClassName styles that frame, the div the sheet measures; padding on it is room the sheet keeps clear, for its shadow.

Parking Citation

City of Bayview

Plate
8KTR204
State
CA
Fine
$63.00
Violation
Expired meter, section 22.2.04
Location
Harbor Way at 3rd St
Issued
10/04 14:52
No. 448120Pay within 21 days

Letterhead#

PaperHeader lays out a PaperSeal, the PaperHeading and a PaperHeaderAside, in that order. The seal and the aside are boxes of the same width, so the heading between them is centered on the sheet, not on the room they leave. The title wraps rather than run under the boxes; captions stack under the subtitle. The seal takes any img or svg: the Seal on these pages is a small inline SVG of the docs' own, drawn in var(--paper-accent) so it follows the sheet's accent.

COUNTY OF BAYVIEW · SHERIFF'S OFFICE ·

Incident Report

Bayview County Sheriff's Office

Patrol Division · Form IR-2

Confidential when completed

Report no.
IR-26-01873
Status
Filed
Form IR-2 · Rev. 01/2026Page 1 of 2

Drop the seal or the aside and keep the other side's box empty (<PaperSeal /> or <PaperHeaderAside />) to hold the heading on the sheet's axis, or drop both and give the heading the whole row.

Fields and boxes#

A PaperRow is a ruled line of PaperFields: a pre-printed label over a typed-in value. grow is a field's share of the row, a flex factor. When a label wraps onto two lines the values in the row still sit on one line, and a value too long for its cell ends in an ellipsis. PaperBox is the same pair boxed on its own, for the aside: a number, a status, a date.

Vehicle Registration

Department of Motor Vehicles · Form REG-343

Plate
8KTR204
Expires
06/30/2027

Registered owner

Full name
Priya Raman
Driver license
Y5520194
Phone
(562) 555-0187
Mailing address
4471 Linden Avenue, Apartment 12B, Long Beach, California 90807
Email
p.raman@mail.com

Vehicle

Make and model
Toyota Prius Prime XSE
Year
2024
Color
Supersonic Red
Vehicle identification number
JTDACACU7R3021874
Odometer at registration
8,412 mi
Fees paid
$412.00

Running text#

PaperText is copy someone reads: terms, a statement, a narrative. It is justified in the serif and keeps the line breaks it was typed with, so text straight from a textarea or a database lands as it was written, paragraphs and numbered clauses included.

Statement of the reporting deputy

At 22:40 on October 3, 2026, I responded to a reported break-in at the Northwind Freight warehouse, 1200 Harbor Way. The east loading door had been forced and its padlock lay on the ground with the shackle cut. The night supervisor, who called it in, walked the floor with me. Two pallets of handheld scanners were missing from bay 14; the rest of the stock appeared untouched. The door, the lock and the empty bay were photographed and logged as evidence.
Reporting deputy
Dep. Alicia Moreno, #4471
Date of statement
10/04/2026

Tables#

PaperTable is a plain table: write the thead and tbody yourself with PaperTableHead, printed like a field label, and PaperTableCell, typed in. Widths are yours too; percentages hold at every scale. When a section has nothing to list, PaperNote says so in place of an empty table.

Evidence

ItemDescriptionQtyLogged by
E-01Padlock, shackle cut, from the east loading door1Dep. A. Moreno
E-02Photographs of the door, the lock and bay 1412Dep. A. Moreno
E-03Security camera footage, east yard, 22:00 to 23:001Sgt. R. Okafor

Witnesses

No witnesses recorded.

Checklist#

PaperChecklist is a list of printed boxes and PaperCheckItem one line of it, ticked with checked. It records what was done; nothing on the sheet can be toggled, so the box is drawn, not a control.

Documents provided

  • Government-issued photo ID
  • Proof of address dated within the last 90 days
  • Bank details for direct deposit
  • Signed confidentiality agreement (Annex B)
  • Commercial driver license, where the role requires one

Documents not ticked are due before the start date.

Signatures#

PaperSignatures sets PaperSignature blocks side by side: a label, the mark over a line, and the name and date under it. The mark is the children: a stored signature as an img (here the SVG a SignaturePad submits), a Signature, or a live SignaturePad given absolute inset-0 so it takes the whole box. Sign the right-hand line: the pad maps the pointer with getBoundingClientRect(), which the sheet's scale never skews, and the date fills in when the first stroke lands. The app's own controls, like Clear here, sit outside the sheet. Left empty, a line waits to be signed.

Equipment Handover

Northwind Freight Co.

Acknowledgement

I received the handheld scanner HS-40 (serial 7Q2-118-604), its charging dock and a safety vest in working order, and I will return them on my last day of work.
Issued by
Signed by Maya Chen
Maya Chen, HR Director10/04/2026
Received by
Daniel Ortega Ruiz
Form HR-210Keep a copy with the employee file

Re-tinting#

The sheet's inks are its own roles, derived from the light theme's tokens: --paper-ink, --paper-muted, --paper-rule, --paper-label (the label tint) and --paper-accent (the title, the section bands and anything you paint with it, like the seal here). The accent defaults to a letterhead navy; set any of them per sheet with a utility.

BAYVIEW COMMUNITY COLLEGE · 1962 ·

Certificate of Completion

Bayview Community College

Continuing Education · 48 contact hours

Certificate no.
CE-26-0912
Issued
09/30/2026

Awarded to

Name
Priya Raman
Course
Forklift Safety and Operation
Result
Pass with merit
Office of the RegistrarPage 1 of 1

Old engines#

Paper is built to hold in old embedded Chromium too, the kind a desktop or game shell ships (Chromium 10x): no container queries, no :has() and no standalone translate or scale anywhere. The fit is one ResizeObserver and one font size; without the observer the sheet is measured once, on mount. Because nothing is zoomed or transformed, a control set into the paper reads its pointer and its box as it would anywhere else, and the type is rasterized at the size it is shown, crisp.

API reference#

Paper

The sheet, an <article> scoped .light, inside the frame it scales into (a <div>). Every article prop goes to the sheet. Every part forwards its element's props and merges className last; paperVariants is the recipe.

PropTypeDefaultDescription
widthnumber52The design width in em of the root type size (832px at 16px). Also set as --paper-width.
fitbooleantrueScales the sheet down to the frame's width, never up. The scale is set as --paper-scale; off, it stays 1 and the container decides what happens to the overflow.
frameClassNamestring-Classes for the frame (the sheet itself takes className).
classNamestring-Merged last on the sheet, where the --paper-* roles live.
Data attributeDescription
data-slot"paper" on the sheet, "paper-frame" on the frame.
CSS variableDescription
--paper-widthThe design width, from width.
--paper-scaleThe fit's scale, from 0 to 1: the sheet's font size, which every length inside is measured in.
--paper-inkThe type. The light theme's --foreground.
--paper-mutedLabels, captions and notes. The light theme's --body.
--paper-ruleEvery rule and box edge.
--paper-labelThe ground of a pre-printed label and the footer.
--paper-accentThe title and the section bands: a deep navy, ink with a little --info in it.
--paper-accent-foregroundThe type on a section band.

PaperHeader

The letterhead row, a <header>: a seal, the heading and an aside of boxes, in that order.

Data attributeDescription
data-slot"paper-header".

PaperSeal

A seal or logo (an img or an svg child), in a <div> boxed as wide as PaperHeaderAside, so the heading is centered on the sheet.

Data attributeDescription
data-slot"paper-seal".

PaperHeading

The centered column, a <div>, for the title, the subtitle and the captions.

Data attributeDescription
data-slot"paper-heading".

PaperTitle

The document's title, an <h2>, in small caps and the accent ink. A very long word wraps anywhere.

Data attributeDescription
data-slot"paper-title".

PaperSubtitle

The issuing body, a <p> in italics under the title.

Data attributeDescription
data-slot"paper-subtitle".

PaperCaption

A line of small print under the title (a jurisdiction, a form number), a <p>. Several stack tight.

Data attributeDescription
data-slot"paper-caption".

PaperHeaderAside

The column on the right of the letterhead, a <div>, for PaperBoxes (a number, a status).

Data attributeDescription
data-slot"paper-header-aside".

PaperBox

A boxed field with its label on top, a <div>: a reference number, a status, a date.

PropTypeDefaultDescription
label*React.ReactNode-The pre-printed label.
childrenReact.ReactNode-The typed-in value.
Data attributeDescription
data-slot"paper-box", with "paper-box-label" and "paper-box-value" inside.

PaperSection

The band that heads a part of the form ("Parties", "Terms"), an <h3>.

Data attributeDescription
data-slot"paper-section".

PaperRow

A row of PaperFields, a <div> ruled underneath.

Data attributeDescription
data-slot"paper-row".

PaperField

One labelled cell of a PaperRow, a <div>. The value is pinned to the bottom, so every value in a row sits on one line when a label wraps.

PropTypeDefaultDescription
label*React.ReactNode-The pre-printed label.
childrenReact.ReactNode-The typed-in value, on one line, ending in an ellipsis when it runs long.
grownumber1The field's share of the row, a flex grow factor.
Data attributeDescription
data-slot"paper-field", with "paper-field-label" and "paper-field-value" inside.

PaperText

Running copy (terms, a narrative), a <div>, justified, keeping the line breaks it was typed with.

Data attributeDescription
data-slot"paper-text".

PaperTable

A ruled <table>. Compose a plain thead/tbody with PaperTableHead and PaperTableCell.

Data attributeDescription
data-slot"paper-table".

PaperTableHead

A column heading, a <th>, printed like a field label.

Data attributeDescription
data-slot"paper-table-head".

PaperTableCell

A typed-in cell, a <td>.

Data attributeDescription
data-slot"paper-table-cell".

PaperNote

What a section says when it has nothing to show ("No evidence logged."), a <p>.

Data attributeDescription
data-slot"paper-note".

PaperChecklist

A list of printed check boxes, a <ul>.

Data attributeDescription
data-slot"paper-checklist".

PaperCheckItem

One line of a PaperChecklist, an <li>: the box, ticked or not, and its text. The box is decorative; the item's text carries the meaning.

PropTypeDefaultDescription
checkedbooleanfalseTicks the printed box.
Data attributeDescription
data-slot"paper-check-item", with "paper-check-box" on the box.
data-checkedPresent when checked.

PaperSignatures

The row of signature blocks, side by side, a <div>.

Data attributeDescription
data-slot"paper-signatures".

PaperSignature

One signature block, a <div>: its label, the mark over a line, and the name and date under it.

PropTypeDefaultDescription
labelReact.ReactNode-What the line is for ("Signature of the issuer"), above it.
nameReact.ReactNode-Who signs, printed under the line.
dateReact.ReactNode-The date, printed under the line at the right.
childrenReact.ReactNode-The mark above the line: an img, a Signature, a typed name, or a SignaturePad with absolute inset-0. Empty, the line waits to be signed.
Data attributeDescription
data-slot"paper-signature", with "paper-signature-label", "paper-signature-mark" and "paper-signature-meta" inside.

PaperFooter

The strip at the foot of the sheet, a <footer>: the form's small print, spread edge to edge.

Data attributeDescription
data-slot"paper-footer".

FAQ#

A Card is part of the app: it follows the theme, reflows with the layout and holds controls. Paper is a document the app shows: it keeps one layout at every size, stays light in a dark theme and reads as something printed, signed and filed.