unfolded

Design system

One set of tokens shared by the Unfolded app and this landing page. Primitives keep the app's own names; components only use the semantic layer on top. Every value below is read straight from src/styles/tokens.css at build time.

Colour

Paper, ink and a single red for errors. Each colour's contrast is measured in the pairing it is used in: dark colours as text on --paper, light colours as a background behind --ink text.

Primitives

  • --ground#ECECEB · 15.58:1 behind ink textAA textthe table
  • --paper#F6F6F5 · 17.04:1 behind ink textAA textthe sheet
  • --paper-shade#E3E3E1 · 14.34:1 behind ink textAA text
  • --paper-crease#D2D2CF · 12.16:1 behind ink textAA text
  • --hairline#BDBDBA · 9.78:1 behind ink textAA text
  • --ink#141414 · 17.04:1 as text on paperAA text
  • --ink-soft#3A3A3A · 10.52:1 as text on paperAA text
  • --muted#666666 · 5.31:1 as text on paperAA text5.3:1 on paper — OK for body text
  • --faint#8C8C8C · 3.11:1 as text on paperLarge text / UI3.1:1 on paper — decoration only, never text
  • --disabled#E0E0DE · 13.94:1 behind ink textAA text
  • --tag#DCDCDA · 13.42:1 behind ink textAA text
  • --on-ink#F6F6F5 · 17.04:1 as text on inkAA text
  • --signal#A8261B · 6.56:1 as text on paperAA texterrors only

Semantic

Semantic colour tokens and the primitive each one points to
TokenPoints toPreview
--color-bgvar(--ground)
--color-surfacevar(--paper)
--color-surface-sunkenvar(--paper-shade)
--color-surface-tagvar(--tag)
--color-bordervar(--hairline)
--color-border-strongvar(--ink)
--color-textvar(--ink)
--color-text-softvar(--ink-soft)
--color-text-mutedvar(--muted)
--color-text-inversevar(--on-ink)
--color-actionvar(--ink)
--color-action-hovervar(--ink-soft)
--color-action-textvar(--on-ink)
--color-errorvar(--signal)

Type

Every family works in English and Hebrew: Frank Ruhl Libre for headings, IBM Plex Sans (and Plex Sans Hebrew) for reading, Newsreader for the wordmark. Sizes from --text-2xl up are fluid — resize the window to watch them scale.

  • Aa--font-wordmark
  • Aa אב--font-display
  • Aa אב--font-ui
  • Aa--font-mono
  1. --text-hero
    The paper folds over your words.כל אחד כתב שורה. אף אחד לא אשם.
  2. --text-3xl
    The paper folds over your words.כל אחד כתב שורה. אף אחד לא אשם.
  3. --text-2xl
    The paper folds over your words.כל אחד כתב שורה. אף אחד לא אשם.
  4. --text-xl
    The paper folds over your words.כל אחד כתב שורה. אף אחד לא אשם.
  5. --text-lg
    The paper folds over your words.כל אחד כתב שורה. אף אחד לא אשם.
  6. --text-md
    The paper folds over your words.כל אחד כתב שורה. אף אחד לא אשם.
  7. --text-sm
    The paper folds over your words.כל אחד כתב שורה. אף אחד לא אשם.
  8. --text-xs
    The paper folds over your words.כל אחד כתב שורה. אף אחד לא אשם.
--weight-regular
400
--weight-medium
500
--weight-semibold
600
--leading-tight
1.05 — display headings
--leading-snug
1.25 — small headings
--leading-body
1.55 — paragraphs
--tracking-tight
-0.02em
--tracking-label
0.08em — uppercase labels / badges
--measure
62ch — comfortable line length for reading

Space & layout

The app's 4px-based scale (1–7), plus two larger steps for the landing page.

  • --space-14px
  • --space-28px
  • --space-312px
  • --space-416px
  • --space-524px
  • --space-632px
  • --space-748px
  • --space-864px
  • --space-996px
--container-max
1200px
--container-narrow
760px
--gutter
clamp(var(--space-4), 4vw, var(--space-7)) — 16 → 48px
--section-y
clamp(var(--space-8), 10vw, 128px) — 64 → 128px

Radii & shadows

Paper has sharp corners. Shadows say how far a sheet sits above the table.

  • --radius-none0
  • --radius-dot2px
  • --radius-field3px
  • --shadow-rest
  • --shadow-lift
  • --shadow-ink

Motion

The app's own timings, now named. Press a row to play it. With reduced motion turned on in your system, every duration collapses to 1ms and nothing travels.

Components

The building blocks in src/components/ui/, plus the signatures from the finished story. Hover and tab through them.

Button

variant: primary · secondary · ghost — size: md · lg. Renders an <a> when given href, otherwise a <button>.

Heading

level (h1–h4, structure) and size (look) are independent.

Hero

3xl — section title

2xl — sub-section

xl — card title

lg — small title

.eyebrow — the small label above every section title.

How it works

From empty page to read-aloud.

Card

variant: paper · outline — interactive adds the hover lift.

Paper

A sheet resting on the table.

Outline

A quieter container.

Badge

variant: outline · solid · soft

2–10 friendsLast callComing soon

Link

variant: default · quiet — external opens a new tab and says so to screen readers.

Default linkQuiet linkExternal link (opens in a new tab)

Mark

The unicorn. variant: app (the app's drawing) · doodle (redrawn in the hero's ink line) — size in px. Winks on hover, or when a script calls wink(). Always decorative.

Signatures

names — real handwritten signatures (traced SVGs in src/assets/img/signatures/), each with its own tilt. A name without a drawing falls back to plain text in --font-display, like “Dana” here, so a new name can never break the page.

Dana

Accordion

items (id, question, answer) · idPrefix keeps ids unique when two share a page · headingLevel fits the page outline (h4 here). Each question is a real button that says whether it's open; several can be open at once. Without JavaScript every answer is simply shown.

2–10 friends. A game runs 6–12 rounds, so there’s room for everyone to write more than once.

No, you can play with friends who are somewhere else too, as long as everyone plays at the same time. But it’s made for being together: a party or an evening in, ending with the story read out loud. There are no notifications on purpose. Everyone plays at once, phones in hand.

No. Unfolded runs in the browser on any phone. Friends join with a link or a 4-digit room code.

Section & Container

Section tone: ground · paper · ink, with --section-y padding. Container width: default (--container-max) · narrow (--container-narrow).

ground
paper
ink

מימין לשמאל · Right-to-left

The same components with dir="rtl" and the app's Hebrew wording. Layout uses logical properties (padding-inline, not padding-left), so nothing needs a mirrored version, and :lang(he) resets the letter-spacing Hebrew doesn't use.

2–10 חברים6–12 סבביםבקרוב

לקפל את הדף

רואים רק את תחילת המשפט. משלימים, מקפלים ומשאירים התחלה לתור הבא.

כל אחד כתב שורה. אף אחד לא אשם.

להציץ

כותבים יחד סיפור אחד, שורה בכל תור.

2 עד 10 חברים. כל אחד מצטרף מהטלפון שלו עם הקוד.

המשחק בוחר מי יכתוב. יש שתי דקות לכל תור.