Reckon is a system for generating whole products, correctly, from one inventory. The component layer was never what failed. A model can be handed 54 primitives and still produce a screen whose totals do not reconcile, whose actions do not follow the record's state, and whose fifth destination looks exactly like the first four. The rules above the components are the product; the components are the floor they stand on.
That splits Reckon into three layers, in the order they matter:
| Layer | Lives in | What it does |
|---|---|---|
| The rules | AGENTS.md, CLAUDE.md, PROMPTS.md |
How screens are assembled and how the values on them are derived. Read before anything is generated; overrides generic defaults. |
| The evidence | templates/ — nine worked products |
Proof the rules produce products a person can tell apart, not descriptions of products. |
| The foundation | styles.css, tokens/, css/, components/, guidelines/ |
207 tokens and 54 component families, so nothing above has to invent a value. |
The rules layer travels on its own — RELEASE.md §4 packages it without the code, because
it is useful in a project that has never seen these components.
Version 1.0.0 — this line is the single source of truth for the version.
CHANGELOG.md records what each version contained; RELEASE.md says how a release is cut.
Reckon is AGPL-3.0-or-later; read NOTICE.md §0 before publishing anything.
- Generating a screen or a product →
AGENTS.md, thenPROMPTS.mdfor the shape a good brief takes. - Designing with the brand → §2 and §3 below, then the cards in the Design System tab.
- Looking for a component → §5, then the family's
.d.tsand.prompt.md.
Reckon's tokens, components and fonts are lifted from the real source of
cosscom/coss — the monorepo behind
coss.com and its component library coss.com/ui (formerly
Origin UI). The tokens are the resolved values of packages/ui/src/styles/globals.css,
the components are recreations of the 54 primitives in packages/ui/src/components/, and
the fonts are the actual .woff2 files shipped in packages/ui/src/fonts/. Nothing here
is invented, which is why the licensing in NOTICE.md is a real question rather than a
formality.
cosscom/coss is a Turborepo containing four surfaces:
| Path | Product | Status |
|---|---|---|
apps/www/ |
coss.com — the holding-company marketing site, written as an open letter | context only |
apps/ui/ |
coss.com/ui — the component library docs, gallery and particle catalogue | context only; MIT source of the registry components |
packages/ui/ |
the shared component package — 54 primitives on Base UI + Tailwind v4 | recreated in components/ |
apps/origin/ |
Origin UI (legacy) — the pre-acquisition Radix/shadcn-style snapshot | source of the logo and imagery only |
coss.com is the holding company of cal.com; coss.com/ui is the library cal.com is
progressively adopting. The library is built on Base UI
primitives, styled with Tailwind CSS v4, and distributed shadcn-style
(npx shadcn@latest add @coss/<component>) — copy, paste and own.
The one-line positioning, in their words, is "the everything but AI company".
https://github.com/cosscom/coss— the only source. Explore it further before building anything ambitious; in particularapps/ui/content/docs/components(per-component MDX docs) andapps/ui/registry/default/particles(412 composed examples) contain far more pattern detail than fits here.apps/ui/skills/coss/SKILL.mdandapps/ui/skills/coss/references/rules/styling.md— the repo's own agent guidance; the rules in §4 below are consistent with it.- No Figma file was provided.
The rules layer has no upstream. §2 and §3 describe a brand that exists; AGENTS.md
describes how to build products with it, and that is Reckon's own work — thirty observed
failures and their corrections, carried across a change of source at 0.7 and a rewrite at
0.9. CHANGELOG.md is the argument in full.
The brand has two registers, and mixing them is the most common mistake.
dear friend,
open source is the foundation of all modern software. every app, website, and system we use today is built on open source.
best, bailey & peer
- Lowercase throughout, including the first word of a sentence and product names
(
ui,calendar,scheduling,auth). Proper nouns stay lowercase too:cal.com,coss.com. - Letter form. The homepage is literally a signed letter. Short paragraphs, one idea each, no headings, no bullet grid, no feature cards.
- "we" and "you". "let us run the infrastructure, so you can focus on writing code."
- Bold is used sparingly to lift a single term out of a paragraph
(
**commercial open source software (coss)**), never for whole sentences. - Occasional dry humour, always understated: "and who knows… maybe one day you can
purchase $COSS on your favourite
stackstock exchange." An ellipsis and a strikethrough carry the joke — never an emoji. - Footer sign-off: "open source, open heart, open mind."
- Headings and titles are sentence case: "A new, modern UI component library built on top of Base UI." / "Invite teammate" / "No bookings yet".
- Buttons are verb-first and specific: "Get started", "Join the waitlist", "Browse 412 particles", "Copy booking link". Never "Submit", "OK", or "Click here".
- Field descriptions are one sentence, ending in a period: "Lowercase letters, numbers and dashes."
- Errors say what to do, not what went wrong internally: "Enter a valid email address."
- Destructive confirmations name the consequence in the title ("Delete '30 min meeting'?" → "Existing bookings stay, but the link stops working immediately."), never "Are you sure?".
- Badges are single words in Title case:
Upcoming,New,Live,Pending. - Empty states always end with the next action.
- No emoji. Not in UI, not in docs, not in copy. The repo README uses none; icons do that job.
- Numerals as digits, versions as
1.18.6, shortcuts as real glyphs (⌘K, not "Cmd+K"). - Code and identifiers always in the mono face, never quoted in prose.
Reckon is a near-monochrome, hairline-driven system. If you remember one thing: depth comes from a 1px inset highlight, not from shadow.
- Eleven achromatic neutral steps carry the entire UI.
--foregroundisneutral-800(not black);--backgroundis pure white in light mode and a 96%-neutral-950 mix in dark. - Borders are alpha, not hex:
--borderis black at 8%,--inputat 10%, so they compose correctly over any surface. In dark mode they flip to white at 6% / 8%. - Muted, secondary and accent are all the same 4% black wash — the difference is semantic, not visual. Resist inventing a fifth grey.
- Five semantic hues only — destructive/red, info/blue, success/emerald, warning/amber, plus the five chart colours. Each has a 500 fill and a darker 700 foreground. Tinted surfaces are always 4% (Alert) or 8% (Badge) of the hue, never a solid fill.
- Saturated colour is a signal, never decoration. The single exception in the whole
brand is the coss.com headline swipe: a blue→purple→orange gradient at 16% opacity
with
mix-blend-mode: hard-light, rotated −1°, behind three words. Do not generalise it. - Dark mode is a token re-resolution under
.dark— no component changes class.
- Cal Sans (variable, 300–700) for absolutely everything visible, including
Kbd. Paper Mono for code,<pre>, and technical strings. Two families, no third. --font-headingis an alias of--font-sansby default.- The wordmark and gallery titles use Cal Sans' custom axes:
font-variation-settings: 'GEOM' 50, 'opsz' 32. That setting is the logotype. - 14px is the desktop UI default; 16px is the mobile one. Nearly every component
declares
text-base sm:text-sm— controls grow on touch so iOS never zooms. - Weight does the emphasis work: 400 body, 500 labels/buttons/active nav, 600 titles, 700 wordmark only.
- Marketing headlines run 48px semibold with
-0.01emtracking; body copy isleading-relaxed(1.625) at 16px, max 42rem wide.
- 4px base unit — but half-steps are real. Buttons are
--spacing(3) - 1pxof horizontal padding because the 1px border is subtracted. Copy exact numbers; do not snap 30px to 32px. - Control heights: 24 / 28 / 32 / 36 / 40px on desktop, each +4px on coarse pointers,
with an invisible
::afterguaranteeing a 44px touch target. - Radii all derive from
--radius: 10px→ 4 / 6 / 8 / 10 / 14 / 16px. Buttons and inputs are 10px, alerts and panels 14px, cards and dialogs 16px, menu items and badges 6px. Nested highlight layers usecalc(radius - 1px). - Container is 1416px with 16/24px gutters.
Every raised element carries three things:
- a 1px border in
--inputor--border, - a very faint shadow (always black at 5% —
xsfor controls,smfor thumbs and active tabs,mdfor tooltips,lgfor menus and dialogs), - a hairline: a
::beforelayer inset to the border, carryingbox-shadow: 0 1px rgb(0 0 0 / 4%)in light mode and0 -1px rgb(255 255 255 / 6%)in dark. Light lights the top edge, dark lights the bottom edge.
Solid buttons swap the hairline for inset 0 1px rgb(255 255 255 / 16%), and on press
replace it with inset 0 1px rgb(0 0 0 / 8%) while dropping the outer shadow — the
control physically sinks. Pressed and disabled states always remove the shadow.
There are no gradients on surfaces, no coloured left borders, and no glows.
- Four durations: 100ms (thumb settle), 150ms (hover/focus/background), 200ms (overlays, accordions, the tab indicator), 500ms (progress and meter fills).
- Easing is
ease-in-outfor overlays andcubic-bezier(0,0,.2,1)elsewhere. Nothing bounces — except the two toast acknowledgements: success scales 1 → 1.025 → 0.99 → 1 over 320ms, error shakes ±3px over 280ms, both oncubic-bezier(.5,1,.89,1). Both are disabled underprefers-reduced-motion. - Overlays enter from
scale(0.98)+opacity: 0and leave the same way. No slide, no fly-in, no blur transition (the backdrop's 4px blur is static). - The skeleton sheen is a 120° gradient over a fixed background, so one light appears to pass across a whole group of skeletons at once.
- Hover on filled controls = the same colour at 90% opacity. On transparent controls
= a 4%
--accentwash. Never a different hue, never a border change (except destructive-outline, which picks up a 32% destructive border). - Press = 90–80% opacity plus the inset flip described above. No scale-down.
- Focus = a 2–3px ring in
--ring(light) or--ringat 48% (dark), offset 1px from the background. Focus never changes the fill. - Disabled =
opacity: .64andpointer-events: none. Never grey text on grey. - Invalid = 36% destructive border, escalating to 64% border + 16% ring on focus.
- Loading = the label goes transparent and a centred spinner appears, so the button never changes width.
- The apps sit on
--sidebar(neutral-50), with cards and popovers on the lighter--card/--popoverplanes. Content is not white-on-white by accident — the tint is the page, the white is the object. - The marketing and docs sites draw two vertical hairlines at the container edges, with an 8px rounded, bordered "node" wherever the header baseline or a section rule crosses them. This is the single most identifiable graphic device in the brand.
- Sticky header: 64px,
--sidebarat 80% with a 4px backdrop blur and a bottom hairline. - Blur is used in exactly two places: the sticky header and the dialog backdrop
(
rgb(0 0 0 / 32%)+ 4px). Nowhere else. - Photography: the only imagery in the source is square user avatars and one profile cover. It is neutral, natural-light, unfiltered — no duotone, no grain, no brand wash. Illustration is not used at all; empty states use a fanned trio of bordered icon tiles instead.
- Lucide is the icon system, full stop —
lucide-reactis imported throughoutpackages/ui. There is no icon font, no sprite sheet, no custom icon set in the repo. Load it from CDN (https://unpkg.com/lucide@0.544.0/dist/umd/lucide.min.js) as the cards and UI kits here do, orlucide-reactin a React app. This is not a substitution — it is the same library the source uses. - 16px, 2px stroke, 80% opacity is the default. Icons scale to 18px inside
xlcontrols and 14px insidexsones; usesize-*-equivalent sizing, never a numericsizeprop. - Decorative icons carry
aria-hidden="true". Icon-only buttons carry anaria-labeland, usually, aTooltip. - A handful of glyphs are hand-drawn paths, not Lucide, and are reproduced exactly in
this system: the checkbox tick (
M5.252 12.7 10.2 18.63 18.748 5.37), the indeterminate dash (M5.252 12h13.496), and the number-field scrub cursor. Keep them. - No emoji, ever. No unicode symbols as icons — with one exception: keyboard glyphs
(⌘ ⌥ ⇧ ↵) inside
Kbd. - Logo:
assets/logo.svg(fill#27272A) andassets/logo-dark.svg(white at 88%), both 117×24 wordmarks taken fromapps/origin/public/.
| File | Purpose |
|---|---|
styles.css |
The single entry point consumers link. @import lines only. |
AGENTS.md |
The rules. How screens are assembled and how their values derive. Read before generating any UI. |
CLAUDE.md |
The project instruction that points every conversation at AGENTS.md. |
PROMPTS.md |
Worked full-product example prompts and the shape of answer each should get. |
README.md |
This guide. |
CHANGELOG.md |
The record: what each version contained, and the argument across all of them. |
SKILL.md |
Agent-Skills front matter so this folder works in Claude Code. |
RELEASE.md |
How a release is cut. Read it before packaging anything. |
LICENSE.md |
AGPL-3.0-or-later, and why. Full text at licenses/AGPL-3.0.txt. |
NOTICE.md |
Every piece of third-party material, its upstream and its terms. §0 carries the licensing decision; items marked UNVERIFIED or UNRESOLVED block a public release. |
github.md |
Source-repo association and sync record. |
thumbnail.html |
The homepage tile. |
fonts.css (@font-face) · colors.css (palette + semantic aliases + .dark) ·
typography.css · spacing.css · radius.css · elevation.css · motion.css
base.css · controls.css · surfaces.css · overlays.css · navigation.css ·
data.css — all classes prefixed o-. Layout and state only; every value is a token.
logo.svg, logo-dark.svg, fonts/CalSansVF.woff2, fonts/PaperMono-Regular.woff2,
and img/ (avatars at 40/80px, avatar.jpg, profile-bg.jpg) — all copied from the repo.
templates/logos/ holds the placeholder marks for the fictional brands templates
invent (01-…04-logo-demo.svg). They come from logoipsum.com
and are free placeholder logos — pick one per template, never draw a new mark.
actions/ — Button · ButtonGroup · Toggle · ToggleGroup · Toolbar
forms/ — Input · InputGroup · Textarea · Label · Field · Fieldset · Form · Select ·
Combobox · Autocomplete · Checkbox · CheckboxGroup · RadioGroup · Switch · Slider ·
NumberField · OTPField
data/ — Card · Frame · Table · Badge · Avatar · Kbd · Separator · Calendar
feedback/ — Alert · Toast · Spinner · Skeleton · Progress · Meter · Empty
overlays/ — Dialog · AlertDialog · Sheet · Drawer · Popover · Tooltip · Menu ·
ContextMenu · PreviewCard · Command
navigation/ — Tabs · Breadcrumb · Pagination · Sidebar · Accordion · Collapsible ·
ScrollArea
Each has a .jsx implementation, a .d.ts props contract and a .prompt.md usage note.
Compound parts (CardHeader, MenuItem, SidebarMenuButton, …) are exported from their
family's file.
Intentional additions: none. Every component maps 1:1 to a file in
packages/ui/src/components/. Two source files are folded into their family rather than
standing alone: checkbox-group.tsx → CheckboxGroup (kept separate), and
base-ui/* helpers, which are runtime plumbing with no visual surface.
Deliberate simplifications: these are cosmetic recreations, not the production
components. Focus trapping, portalling, collision-aware positioning, virtualised lists
and the full Base UI keyboard contracts are not reimplemented — use the real
@coss/ui package for production.
22 specimen cards across Colors, Type, Spacing, Elevation, Motion and Brand, rendered in the Design System tab.
Nine worked products, each a self-contained folder with its own entry, shell, screens and
fixtures. They are the evidence that the rules and the components produce screens; read
AGENTS.md before adding a tenth.
No recreation of the upstream sites is kept here. The system is read through its cards and its templates.