One typographic language bound to the data-font axis: Heading (level and size decoupled), Text with sizes, tones and truncation, Lead, Code, Blockquote, Numeric, and Prose for rich content from the editor or CMS. Server-compatible.
Dinner, slowly.
Seasonal plates from the Aegean coast, served at one long table in Moda.
Spring menu
Starters
Grilled octopus, fava, capers
Allergens
Dinner, slowly.
Seasonal plates from the Aegean coast, served at one long table in Moda.
Spring menu
Starters
Grilled octopus, fava, capers
Allergens
Dinner, slowly.
Seasonal plates from the Aegean coast, served at one long table in Moda.
Spring menu
Starters
Grilled octopus, fava, capers
Allergens
Installation
The whole kit as one package — get updates by bumping the version. Add the styles to globals.css: @import "@vamos-ui/react/styles.css";
Usage
import { Heading, Text, Prose } from "@vamos-ui/react";
<Heading level={1} size="display">Dinner, <em>slowly</em>.</Heading>
<Text tone="muted">Last edited 3 minutes ago.</Text>
<Prose html={post.bodyHtml} />Headings use text-wrap: balance, paragraphs pretty; Prose hyphenates by the lang attribute and sets <q> quotes per language.
<em> inside display headings follows the preset: italic in serif presets (editorial), upright in sans presets.
Examples
Text
Four sizes, tones, weights; truncate for one line, truncate={n} for a line clamp. The full text goes into title.
Large · 16px — website body and long forms.
Medium · 14px — the panel default.
Small · 13px — table cells, secondary actions.
Extra small · 12px — captions and meta.
Muted — Last edited 3 minutes ago by Elif.
Subtle — Draft · not indexed by search engines.
Accent — 12 new leads this week.
Success — Payment of $1,260.00 received.
Danger — The card was declined (insufficient funds).
Why we moved our booking flow to a single page and what happened to the conversion rate
We replaced a four-step wizard with one scrolling page. Abandonment dropped by a third, phone bookings halved, and the average party size went up — here is everything we measured over twelve weeks, including the parts that didn't work.
Slug: single-page-booking-flow
Prose (article)
Raw editor output styled by tokens: headings in the preset face, lists, quote, code, a table in a focusable scroll region (ProseTable). Sits on a surface, not on the glass scene.
A slower kind of service
When we opened in Moda in 2019, we had eleven tables and one rule: nobody is rushed. Five years later we have one long table, a set menu that changes every week, and the same rule. This is how a dinner at Sofra works.
The evening
Doors open at 19:00. Dinner starts at 19:30 whether everyone is seated or not — the first course is always something to share, so late guests catch up easily.
- Six courses, served family-style.
- A natural-wine pairing, or a non-alcoholic one made in house.
- Allergies? Tell us when you book — we cook for gluten-free, vegetarian and nut-free guests every night.
The best restaurant meal I've had in Istanbul, and I'm from here.
— Ayşe Demir, Istanbul Eats
Prices
| Option | Weeknights | Fri – Sat |
|---|---|---|
| Set menu | $68 | $78 |
| Wine pairing | $42 | $42 |
| House pairing (0%) | $24 | $24 |
Cancel up to 24 hours before for a full refund. Use code SPRING24 at checkout for a glass of pét-nat on arrival.
Numbers
Numeric lines figures up (tabular); signOf colours a change. Format with createFormatter / useFormat first.
Mono variant for IDs: INV-2041 · ORD-88310
Admin page header
level={1} for the outline, size="xl" for the look — headings never skip a level for visual reasons.
CRM · Pipeline
Deals in motion
42 open deals worth $684,200 · 9 closing this month
API
Heading
| Prop | Type | Default |
|---|---|---|
levelSemantic level (<h1>…<h6>). | 1 | 2 | 3 | 4 | 5 | 6 | 2 |
size56 / 44 / 32 px × --display-scale, 22, 17 px. display and xl use the heading face. | "display" | "xl" | "lg" | "md" | "sm" | from level |
asChildApply the styles to the child element. | boolean | — |
Text
| Prop | Type | Default |
|---|---|---|
asElement. | "p" | "span" | "div" | "label" | "small" | "strong" | "figcaption" | "p" |
size12 / 13 / 14 / 16 px. | "xs" | "sm" | "md" | "lg" | "md" |
toneColour from tokens. | "default" | "muted" | "subtle" | "accent" | "danger" | "success" | "warning" | "inherit" | "default" |
weightFont weight. | "regular" | "medium" | "semibold" | — |
truncatetrue = one line with ellipsis; n = clamp to n lines. | boolean | number | — |
tabularTabular figures. | boolean | — |
asChildApply the styles to the child element. | boolean | — |
Prose
| Prop | Type | Default |
|---|---|---|
sizeBase size 14 / 16 / 18 px; everything inside scales in em. | "sm" | "md" | "lg" | "md" |
htmlRaw HTML (sanitize on the server first). | string | — |
fullWidthRemove the --measure (64ch) cap. | boolean | — |
asChildStyle your own element (e.g. <article>). | boolean | — |
ProseTable
| Prop | Type | Default |
|---|---|---|
labelRequired. Names the keyboard-scrollable region around a wide table. | string | — |
Lead · Code · Blockquote · Numeric
| Prop | Type | Default |
|---|---|---|
Blockquote attributionRendered as the figcaption. | ReactNode | — |
Numeric monoCode font instead of tabular UI figures. | boolean | — |
Numeric signOfNegative → danger, positive → success. | number | — |