@alanbuendia/folio
v1.0.0
Published
Folio — a light-first React design system for office software: dense tables, calm forms and dependable overlays.
Maintainers
Readme
Folio Design System
Folio is a React component library for oficinista (office-worker) interfaces — dense, professional internal tools: dashboards, admin panels, account managers, settings. The aesthetic is light-first and sober: real white surfaces, restrained type, and an ink-blue accent used by the eyedropper. Depth comes from three grays and 1px lines, never from boxes or hard shadows. There is no dark mode.
Think: corporate software you trust with the numbers. Calm, dense, legible, unfussy.
Install
npm i @alanbuendia/folioreact and react-dom (>=18) are peer dependencies — bring your own. Import the
stylesheet once at your app root (it carries the design tokens + component styles):
import '@alanbuendia/folio/styles.css';
import { Button, Table, ToastProvider, useToast } from '@alanbuendia/folio';
export default function App() {
return (
<ToastProvider>
<Button variant="primary">New account</Button>
</ToastProvider>
);
}Sources
This system was authored from a written brand brief (no external codebase or Figma was attached). The typeface is IBM Plex — the genuine brand font, free via Google Fonts; @font-face rules point at Google's static woff2 hosting (tokens/fonts.css). If you have licensed/self-hosted IBM Plex binaries, drop them in assets/ and update those src: URLs.
Content fundamentals
How Folio writes copy:
- Voice: plain, precise, operational. It names things accurately and stops. No marketing gloss, no exclamation, no hype.
- Person: address the user as you ("Sign out inactive sessions automatically"); the product refers to itself as Folio, rarely "we".
- Casing: Sentence case everywhere — buttons, headings, menu items ("New account", not "New Account"). The only uppercase is the mono overline/eyebrow label (
.folio-overline), used for section kickers and KPI labels. - Numbers & data: always IBM Plex Mono with tabular figures — money, counts, IDs (
ACC-04821), dates (2026-06-21), deltas (+12.4%). Money is explicit:$48,690. - Labels: terse nouns ("Owner", "Region", "MRR", "Renews"). Helper text is one calm sentence ("As it appears on invoices and filings.").
- Status: a small vocabulary — Active / Pending / Overdue / Draft / Enterprise. Lower-stakes than it sounds; stated, not shouted.
- Emoji: none. Ever. Icons carry meaning instead.
- Tone example — a destructive warning: "This permanently removes all accounts, invoices, and members. This cannot be undone." Direct, no drama.
Visual foundations
Color. White (#FFFFFF) is the canvas — used generously, never tinted. Text and structure are the three grays: #18181B (primary), #52525B (secondary), #A1A1AA (muted/icons). The single structural line is #EAEAEA at 1px. The accent is ink blue #2D4A7C, used con cuentagotas — one or two touches per view: the primary button, the active nav item, a focus ring, a selected row tint (#EEF2F8). Semantic colors are deliberately muted and desaturated so they sit inside the sober palette rather than fighting it: success #2F6F4F, warning #8A6D1F, danger #9A3D38 — each paired with a faint tint for fills.
Type. IBM Plex, three roles, strictly separated:
- Serif (display) — page and section titles only. Weight 500. Gives the system its quiet editorial authority.
- Sans (UI/body) — everything interactive and prose. Base 14px; 13px in dense rows.
- Mono (data/labels) — figures, IDs, dates, and the uppercase overline. Tabular numerals.
Spacing. 4px grid. Dense by default — generous enough to breathe, tight enough to show a lot at once. Page gutters 24px; card padding 20px; table cells 11px vertical (8px when dense).
Backgrounds. Flat white. No gradients, images, textures, or patterns anywhere in the UI chrome. The folded-page logo mark is the only illustrative element.
Depth. The 1px line is the primary hierarchy device — borders group, dividers separate. Shadows are reserved exclusively for true overlays (menus, dialogs, toasts) that float above the page: soft, low, --shadow-popover (very diffuse, very low opacity — never a hard shadow). Cards are flat: 1px border + 6px radius, no shadow.
Borders & radii. 1px solid #EAEAEA (or #D4D4D8 for input borders / hover). One subtle radius does most of the work — 6px for inputs, buttons, cards, and menus; 10px for dialogs; pill (999px) reserved for badges, avatars, status dots, and the switch.
Corners & cards. A Folio card = white fill, 1px --line border, 6px radius, optional header/footer divided by 1px rules; the footer sits on a --gray-50 sunken bar. Never a colored left-border accent, never a drop shadow.
Animation. Sober and functional — one expo curve (cubic-bezier(0.16,1,0.3,1)) settles everything; no bounces, no springs, no decorative loops. Motion is centralised in folio/motion/tokens.css (--ease-out, --dur-1..4) and every animation is transform/opacity-based (so content is never hidden when paused) and gated behind prefers-reduced-motion. The refined micro-interactions are: a sliding tab underline, an animated-height accordion, a fade+scale tooltip/menu/popover, a shimmer skeleton, an indeterminate progress bar, count-up stats, and grow-in chart bars. Reusable helpers ship with the library: useReducedMotion, useInView, usePresence, CountUp, plus Portal / Popover / useAnchoredPosition for anchored overlays.
Overlays. Anything floating (Dialog, Drawer, Menu, Combobox, Tooltip, Command Palette, Toaster) renders through a portal to <body> so it escapes any transformed/clipping ancestor, and closes on Escape / outside-click. The Toaster (ToastProvider + useToast) adds stacking, slide-in/out and auto-dismiss.
Hover states. Subtle: secondary/ghost controls fill to --gray-50; table rows fill to --gray-50; the primary button darkens to --ink-hover. Never scale or lift.
Press / active. Color shift only (darker ink, tint fill) — no shrink, no shadow. Active nav and selected rows use the --ink-tint wash with ink text.
Focus. 2px ink outline (:focus-visible) or a soft 3px ink ring on text fields (--focus-shadow). Always visible, always ink.
Transparency & blur. Not used. Surfaces are opaque. (The only translucency is inside shadow rgba.)
Imagery. None by default. Avatars are mono initials on a neutral fill with a hairline border (square for organisations, circle for people).
Iconography
- Set: a curated subset of Lucide (MIT) — the line family that matches Folio's 1px structural aesthetic. Stroke-based, 2px stroke,
currentColor, 16px default (14px in dense tables). - Delivery: shipped as the
Iconcomponent (components/core/Icon.jsx) with inline path data — no icon font, no external request, no SVG files to manage. Reference by name:<Icon name="search" />. - Substitution note: the brief specified no icon set, so Lucide was chosen as the closest fit to the line aesthetic. If you'd prefer a different family (e.g. Phosphor, Heroicons), swap the path dictionary in
Icon.jsx— the API stays the same. - Emoji / unicode: never used as icons.
- Logo: the folded-folio mark (
assets/folio-mark.svg) and horizontal lockup (assets/folio-wordmark.svg) are drawn in 1px ink line to match everything else.
Prototype
prototype/index.html is a functional, navigable product built entirely from the system's own components — the reference for how Folio feels in motion. A left sidebar switches between four screens, each with real interactivity:
- Components — a showcase of palette, type specimen, buttons, inputs, badges, and a calm "Density" table, each annotated with a mono ficha spec label (variant, radius, focus…) like an archive tab.
- Dashboard — serif metric tiles over a dense accounts table, with an overdue-invoices banner.
- Accounts — full table with a search box that filters rows live and status dots.
- Settings — an editable form with a working switch and live validation (helper text turns red when a required field is emptied).
A New account dialog opens with a subtle fade+scale; screen changes use a short transform slide; rows and buttons have real hover/active/focus states. All motion is transform-based and gated behind prefers-reduced-motion, and the layout is responsive (the sidebar collapses to a drawer under 860px).
Index / manifest
Root:
styles.css— the single entry point consumers link (@importlist only).tokens/—fonts.css,colors.css,typography.css,spacing.css,base.css.assets/—folio-mark.svg,folio-wordmark.svg.guidelines/— foundation specimen cards (Type, Colors, Spacing, Brand).readme.md(this file),SKILL.md.
Components:
- core/ —
Icon,Button(+loading),IconButton,Badge,Tag,Card,Avatar,Divider,Kbd,Spinner - forms/ —
Input,Textarea,Select,Combobox,Checkbox,Radio,Switch,Field - navigation/ —
Tabs,Breadcrumb,SidebarNav,Accordion,Pagination,Menu,CommandPalette - data/ —
Table,StatTile - feedback/ —
Banner,Tooltip,Dialog,Drawer,Progress,Skeleton,Toast,ToastProvider/useToast - overlays/ —
Popover,Portal,useAnchoredPosition - backgrounds/ —
Aurora,Spotlight,DotField,GridLines - motion/ —
useReducedMotion,useInView,usePresence,CountUp/useCountUp
UI kits:
- ui_kits/folio-console/ — the Folio Console: an interactive shell (sidebar + topbar) with Dashboard, Accounts (dense, sortable, filterable table), and Settings screens.
index.htmlis the click-through entry.
Prototype:
- prototype/ — the functional product prototype (see the Prototype section above). Screens are
ProtoDashboardScreen/ProtoAccountsScreen/ProtoSettingsScreen/ComponentsScreen, wired byShell.jsxinindex.html. Named with aProtoprefix so they don't collide with the UI-kit screens in the bundle namespace.
Each component directory has a .d.ts (props contract), .prompt.md (usage), and a @dsCard HTML specimen. The _ds_bundle.js, _ds_manifest.json, and _adherence.oxlintrc.json files are generated by the compiler — do not edit them.
