Official Showcase: Explore the interactive specimens, test the variable axes, drag stickers around, and see the origin story at cal.com/font.
Cal Sans Text UI is the interface cut of Cal Sans v2, designed by Mark Davis for Cal.com. Every axis of Cal Sans is live here except size: opsz is pinned at the 10 pt interface drawing, and weight, geometry, ascender height and the drawn italic stay yours. It is optimized at the pixel level for 14–15px interfaces on high-DPI screens, and works well either side of that; for headlines and short display settings, reach for Cal Sans itself, which adds the full 8–45 pt optical range.
| Axis | Tag | Range | Default | Description |
|---|---|---|---|---|
| Weight | wght |
400–700 | 400 | Regular–Bold |
| Geometric Formality | GEOM |
0–100 | 25 | A11y (0) → UI (25) → Base (50) → Geo (100) |
| Ascender Height | YTAS |
1440–1600 | 1520 | Cal Sans ships it at 1440; this cut raises it to 1520 for more open sentence shapes at text size |
| Sharp | SHRP |
0–100 | 0 | Corner sharpness |
| Italic | ital |
0–1 | 0 | Upright to the drawn 9.5° italic |
Every Cal Sans v2 axis is live here except one:
| Frozen | Value | Why |
|---|---|---|
opsz |
10 | The interface drawing throughout — no 8 pt, no 45 pt. Everything else stays adjustable. |
Italic is an axis, not a second face.
font-style: italiccannot reach a variable axis, so<em>and<i>will not italicize from the variable file alone — ask for it directly, and restate any other axes you rely on, becausefont-variation-settingsresets what it omits:em { font-variation-settings: "ital" 1, "GEOM" 25, "YTAS" 1520; }The static faces in
ui-non-variable.cssship drawn italics per weight, sofont-style: italicworks normally there.
GEOM0 changes more than shape. At the A11y end,rcltswaps in the seriffed I and curved l on its own, with no feature applied — shaping "Il1" atGEOM0 returnsI.rcltA11yandl.rcltA11y. At the default 25 you get the plain forms.GEOM100 also switches the numeral 1.
The most Bauhaus-minded designs struggle when they are actually read: geometry that looks immaculate on a poster can close up and blur together at 14px. So the drawing is tested where it has to survive.
The acid test is blur. It simulates moving eyes, poor light, a far screen and low vision, and it separates type that reads from type that poses.
Nothing is subset out of this cut: 20 stylistic sets and 42 character variants ship, toggled wherever OpenType features are exposed. The full catalog lives in Cal Sans' character-alternatives doc.
Availability: Modern browsers and font feature-rich applications like Framer, Figma, Photoshop/InDesign/Illustrator/AfterEffects, and Affinity.
Cal Sans began as a font that had to operate in two worlds: mild-mannered UI and braggadocious marketing. It grew into four, adding a highbrow Geo set that would make Ed Benguiat and Paul Renner proud, and an A11y set drawn for even easier reading. Every one ships in this package, named at its stop on the slider: Cal Sans Text A11y (0), Cal Sans Text UI (25), Cal Sans Text (50), and Cal Sans Text Geo (100), each drawn in the specimens on this page.
The straight l is the default lowercase l in this family. The curved, tailed l comes from the A11y end of the axis: at GEOM 0, rclt swaps in both the tailed l and the seriffed I on its own, with no feature applied. ss18 and ss19 reach the same forms where the axis is not available.
Availability: The same browsers and applications, shipped complete on npm. The Google Fonts cuts subset these out.
All 20 sets and 42 variants, toggled wherever features are exposed; the full catalog is linked above.
Two caveats found while testing this build:
ss17(Geometric/legible 6 and 9) has no plainsix/ninein its input set, so it only takes effect together withss16; andss20("Horizontal Sharps") mapsZ/z/5, not the sharp s.
Availability: ReCal Sans Font Builder; the result works anywhere you can upload a font, like PowerPoint or Canva.
Choose new defaults and freeze tabular figures and other OpenType features into something new, online, no command line or font software needed. Your favorite settings become the font’s only settings. Hosting for custom builds is available too.
Swapping a UI font shouldn’t mean re-tuning every button, badge and input. Cal Sans Text UI is drawn to the same vertical proportions as the system and open-source faces interfaces already ship with, so at the same font-size it sits in the same space.
Above, each face is set at an equal size and stacked on one baseline. Cal Sans is the solid shape; the others are outlines. Every one of them has capitals within 3% of Cal Sans’s, and Cal Sans holds its x-height at 71.5% of cap height, inside the band those faces span.
| Typeface | Cap height | x-height |
|---|---|---|
| Cal Sans Text UI | 100.0% | 71.5% |
| Segoe UI | 97.2% | 69.4% |
| TikTok Sans | 97.9% | 73.0% |
| Helvetica | 99.7% | 72.6% |
| SF Pro Text | 97.9% | 73.1% |
| Inter | 101.0% | 75.8% |
| Roboto | 98.7% | 73.4% |
| Google Sans Flex | 99.4% | 72.4% |
Each face at the same font-size, measured from its own H and x, as a percentage of Cal Sans’s cap height.
Cal Sans Text UI is an open-source alternative to Inter, Roboto and SF Pro for product UI: free under the SIL Open Font License, variable from Regular to Bold, and it sits beside the system stack without resizing a component.
Two numbers decide whether a font behaves inside a component: how deep the descenders reach, and how far the line box sits off cap-center.
Descenders reach 31.9% of cap height below the baseline, so mixed-case labels still read as mixed case at 12px. And the line box is cap-centered to within 0.02 em: the space above the capitals matches the space below the baseline, so a label sits in the optical middle of a button, badge or input. No nudging, no one-pixel padding hack.
For Next.js, Vite, CRA, or any app that can import CSS:
npm i @calcom/cal-sans-uiNext.js: peer dependency Next.js 13.2+
Next.js (App Router). The package ships a next/font/local wrapper:
import { CalSansUI } from "@calcom/cal-sans-ui/ui";
export default function RootLayout({ children }) {
return (
<html lang="en" className={CalSansUI.variable}>
<body>{children}</body>
</html>
);
}Anywhere else — Vite, CRA, plain HTML — import the stylesheet and use the family name:
import "@calcom/cal-sans-ui/ui.css";body { font-family: "Cal Sans Text UI", sans-serif; }Tailwind. Point a family at the CSS variable the wrapper sets:
// tailwind.config.js
theme: { extend: { fontFamily: { sans: ["var(--font-cal-sans-ui)", "sans-serif"] } } }| Import | Description |
|---|---|
@calcom/cal-sans-ui |
Next: CalSansUI, CalSansUINonVariable. Preferred. |
@calcom/cal-sans-ui/ui |
Next: CalSansUI (variable, roman + italic). |
@calcom/cal-sans-ui/ui-non-variable |
Next: CalSansUINonVariable (8 statics). |
@calcom/cal-sans-ui/ui.css |
CSS: variable font, roman + italic. |
@calcom/cal-sans-ui/ui-non-variable.css |
CSS: 4 weights × roman/italic. |
As of v2.0.0 this package ships a single family, Cal Sans Text UI — the UI cut of
Cal Sans v2, instanced at the coordinates above. The
three 1.x families are archived at tag 1.500,
and the geometry they exposed through GEOM now lives on the GEOM axis of the full
Cal Sans variable font. The design notes below describe that 1.x work.
Afrikaans • Albanian • Asturian • Asu • Azerbaijani • Basque • Bemba • Bena • Bosnian • Breton • Catalan • Cebuano • Chiga • Colognian • Cornish • Corsican • Croatian • Czech • Danish • Embu • English • Esperanto • Estonian • Faroese • Filipino • Finnish • French • Friulian • Galician • Ganda • German • Gusii • Haitian Creole • Hawaiian • Hungarian • Icelandic • Ido • Igbo • Inari Sami • Indonesian • Interlingua • Irish • Italian • Javanese • Jju • Jola-Fonyi • Kabuverdianu • Kalaallisut • Kalenjin • Kamba • Kikuyu • Kinyarwanda • Latvian • Lithuanian • Lojban • Lower Sorbian • Luo • Luxembourgish • Luyia • Machame • Makhuwa-Meetto • Makonde • Malagasy • Malay • Maltese • Manx • Māori • Mapuche • Marshallese • Meru • Mohawk • Morisyen • Mvskoke • North Ndebele • North Sámi • Northern Sotho • Norwegian Bokmål • Norwegian Nynorsk • Nyanja • Nyankole • Occitan • Oromo • Pite Sámi • Polish • Portuguese • Quechua • Romanian • Romansh • Rombo • Rundi • Rwa • Samburu • Samoan • Sango • Sangu • Sardinian • Scottish Gaelic • Sena • Serbian • Shambala • Shona • Sicilian • Slovak • Slovenian • Soga • Somali • South Ndebele • Southern Sotho • Spanish • Sundanese • Swahili • Swati • Swedish • Swiss German • Taita • Taroko • Teso • Tongan • Tsonga • Tswana • Turkish • Turkmen • Ume Sámi • Upper Sorbian • Uzbek • Vietnamese • Vunjo • Walloon • Welsh • Wolastoqey • Wolof • Xhosa • Zulu
Thank you to Peer for commissioning this project. I wanted to also thank Wei Huang for his Open Source “Perfect Glyphs Example File” that is Work Sans dot glyphs. Incredibly helpful, and exhibits genius.
The following people were invaluable to this project, in no specific order, with an undisclosed amount of personal (or impersonal) influence:
- Paul Renner
- Roger Black, David Berlow, Tobias Frere-Jones, Matthew Carter, Jonathan Hoefler
- Hannes Famira, Cara Di Edwardo, Andy Clymer, David Jonathan Ross, Thomas Jockin
- ArrowType’s Type-x Chrome extension Chrome Store Link
- Eva Roa my love, ᴡᴏʀᴅᴍᴀʀᴋ COO and resident Python expert and evaGPT terminal; Doriel Jacov
- As Cal Sans Text and Cal Sans UI are the fruit of my labor, I am the fruit of Scott & Lori Davis
Measured against the 1.500 build.
Text will not reflow. Cap height (721 → 720) and x-height (514 → 514) are unchanged per 1000 em, and a line of UI copy runs within 1% at every shared weight. Existing layouts keep their line breaks.
What changes:
| 1.500 | 2.009 | Note | |
|---|---|---|---|
| Weight range | 300–700 | 400–700 | Light is gone. font-weight: 300 now clamps to 400. |
| Regular/Medium color | — | ~10% lighter | Stems at 400 and 500 are lighter; 600 and 700 are identical. |
GEOM axis |
0–100 | 0–100, default 25 | Still live; the default moves from 0 to 25 (UI). |
| Default line box | 1.12 em | 1.30 em | Set line-height explicitly if you relied on the default. |
| Italics | none | drawn, 9.5° on ital |
New — but as an axis, so font-style: italic does not reach it in the variable file. |
| Stylistic sets | 5 sets, 8 variants | 20 sets, 42 variants | Nothing is subset out — see the numbering warning below. |
| Glyphs | 1069 | 1546 | |
| Characters | 682 | 695 | 15 added; U+00AD soft hyphen and U+0335 combining short stroke overlay dropped. |
| Package exports | ./ui ./text ./geo |
./ui |
./text and ./geo are removed. |
ss02andss06changed meaning. The alternates are renumbered on Cal Sans v2's scheme, so three tags now reshape a different letter than they did in 1.x. Old feature strings will not error — they will quietly do the wrong thing.
tag 1.500 2.009 ss01Single-story a Geometric a ss02UI G Humanist a ss06Flat y Geometric G ss10,ss11Futura alternatives (+ ligations) unchanged The full catalog is in Cal Sans' character-alternatives doc.
The three families are archived at tag 1.500 and remain installable as
@calcom/cal-sans-ui@1.3.0.
- v2.0.0 — Replaced the three 1.x families with Cal Sans Text UI, a cut of Cal Sans v2.003 carrying every axis except
opsz, which is frozen at 10:wght400–700,GEOM0–100,YTAS1440–1600 (default raised to 1520),SHRP0–100 andital0–1, unsubset, with drawn italics. Breaking:./textand./geoare removed. - v1.500 — Added the GEOM variable axis to the Google Fonts release
- v1.000 — Launch Fonts
These fonts are no longer built from sources/CalSansUI.glyphs. They are a cut of
Cal Sans v2, made from that repo's variable font
by pinning one axis and leaving the rest alone:
| Pinned | opsz 10 — the interface drawing, no 8 pt and no 45 pt |
| Live | wght, GEOM, YTAS (default raised to 1520), SHRP, ital |
| Not applied | the curved-l default swap that the Google Fonts Text UI cut uses |
| Not applied | the ssXX/cvXX subset that the Google Fonts cuts use |
The last two are what separate this from calsans-gf-api-textui in that repo,
which is otherwise pinned at the same place: this build keeps all 20 stylistic
sets and 42 character variants, and ships the plain l as default.
Not yet reproducible from a commit. This cut is not defined in Cal Sans'
scripts/config.py, sopython3 -m scriptswill not regenerate it — it was produced by instancingfonts/calsans-var-full/CalSansVF.ttfwith those pins. Adding it there, alongsideGF_TEXTUI_PINNED, is the outstanding job before anyone can rebuild what npm ships.
The archived 1.x pipeline lives at tag 1.500.
Copyright (c) 2026, Mark Davis mark@wordmark.nyc, with typefaces “Cal Sans UI,” “Cal Sans Text,” and “Cal Sans Geo.” Commissioned by Peer Richelsen for Cal.com. This Font Software is licensed under the SIL Open Font License, Version 1.1, also available with a FAQ at https://openfontlicense.org.
