| name | Permit.io Docs | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| description | Developer documentation for Permit.io, on the www.permit.io brand tokens. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| colors |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| typography |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| rounded |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| spacing |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| components |
|
A calm reading surface on the www.permit.io brand. Warm paper-like light surfaces and deep navy dark surfaces, one purple that means "you can act on this", orange held back for rare emphasis, and three typefaces with fixed jobs: Manrope reads, Rajdhani labels, IBM Plex Mono is code. The docs are a Read surface (guides, concepts) and an Operate surface (reference tables, code tabs), so hierarchy comes from type weight, spacing and hairlines, not from decoration.
The source of truth is code: src/css/tokens.scss (brand and semantic tokens, with every contrast ratio), src/css/base/_infima.scss (tokens mapped onto Infima), src/css/base/_typography.scss (type scale), src/css/components/* (one partial per surface) and src/css/prism/{light,dark}.js (syntax colours). The frontmatter above mirrors those files; when they disagree, the SCSS wins and this file is stale.
The Mirror Rule. Brand tokens mirror the www.permit.io website's global stylesheet. Change a brand value in both places together, and record why here.
Every colour is a role, defined once in tokens.scss for light (:root) and re-resolved for dark ([data-theme='dark']). Components consume --pm-* tokens or the Infima variables mapped onto them, never raw hex.
- Permit purple (light
purple, darkpurple-dark-theme): fills, rules and icons. The active sidebar and TOC rule, the active tab underline, focus rings, highlighted code lines, card hover borders. - Link purple (light
link, darklink-dark-theme): every purple text. Links, active navigation labels, primary button fills. In dark mode it is one lightness step above the brand purple, the lightest step that clears 4.5:1 on surface-3.
- Akita orange (light
orange, darkorange-dark-theme): rare emphasis only. In light mode it is 3.62:1 on the page, so it never carries body-size text there; use it for large marks and non-text accents.
- Page and surfaces (
bg,surface-1..3, and their dark twins): four steps of warm cream in light, four steps of navy in dark. Page, then raised panels (cards, footer, zebra rows), then code and table heads, then code title bars. - Text (
text,text-muted): primary copy and secondary copy. Both clear AA body contrast on every surface in both themes. - Borders:
--pm-border(12% ink light, 10% white dark) for decorative hairlines;--pm-border-strong(55% / 40%) where a boundary identifies a control and needs 3:1.
success, warning, danger and note (= text-muted) drive admonitions. Each is exposed as an -rgb channel so tints are plain rgb(... / alpha) at 7% (light) or 10% (dark) over the page.
The One Purple Rule. Purple means interactive or current. Do not spend it on decoration; a purple thing on the page should be clickable, focused, or the current location.
The Measured Contrast Rule. Every new foreground/background pair gets its ratio written next to the token in tokens.scss, measured on all four surfaces in both themes. scripts/audit-a11y.mjs must stay at zero.
Intentional exceptions to generic checks. A warm cream page and a purple accent both match generic "AI palette" detectors. Here they are the pinned www.permit.io brand, not a default, and stay.
- Manrope (variable 200-800, self-hosted, Latin subset): body, headings, UI.
- Rajdhani 600: small uppercase labels that name a kind of thing (admonition type, sidebar section group, TOC heading, code tab bar). Never sentences.
- IBM Plex Mono 400/500: code, file names, method names. Upright only.
- Page title (h1, 2.25rem / 700, 1.875rem below 996px) with a 1.125rem muted intro for the first one or two paragraphs.
- Section (h2, 1.625rem / 700, 3.75rem above) and subsection (h3, 1.25rem / 700, 2.8125rem above), each 0.9375rem above its content; a heading stacked directly under another sits 1.25rem below it. Sections are separated by space, never by a rule.
- h4-h6 (1.0625 / 1 / 0.875rem, 700) lean on weight rather than size.
- Body 1rem / 1.7. Paragraphs, lists and quotes are capped at
--pm-measure(34rem, about 75 characters); code, tables and figures use the full column. - UI text 0.8125-0.875rem / 500 in navigation, TOC, breadcrumbs, table cells (0.9375rem).
- Code 0.8125rem in blocks, 0.875em inline (never below 12px, including inline code in TOC entries).
- Label Rajdhani 0.75-0.8125rem, uppercase, 0.12em tracking.
The Label Rule. Rajdhani uppercase is for one-to-three word names of a category. A title a reader has to read as a phrase (a custom admonition title, a question) is set in Manrope sentence case.
The Twelve Pixel Floor. No text below 0.75rem (12px), labels included.
- Docs frame: navbar (60px), a 300px sidebar with a hairline right border, the article column capped at
--doc-item-container-width(42rem) and centred in the space left of a 16rem sticky TOC. Below 996px the sidebar becomes a drawer and the TOC is hidden. - Article gutter 1rem; top gutter 2.2rem.
- Home and landing pages (
full_width_container) use a 76rem page with their own gutter (1.5rem, 1rem below 576px). - Spacing follows a 4px base (0.25rem steps): tight 0.25-0.5rem inside a group, 1-1.5rem between blocks, 2.25-3rem above headings.
- The column must shrink before the TOC does: a page that widens its container (frontmatter or MDX) can never push the TOC off-screen.
The Proximity Rule. Space above a heading is always larger than space below it, and a lead-in sentence binds to the list it introduces.
Flat. Depth is expressed with surface steps and 1px hairlines, not shadows. The only shadows are focus rings (--pm-focus-ring: 2px page-colour gap, 2px purple) and Infima defaults that are switched off (--ifm-global-shadow-lw: none on code blocks).
The No-Glow Rule. No coloured or zero-offset glow shadows, in either theme.
- 0.375rem: inline code, small buttons, sidebar item corners.
- 0.5rem: controls, tables, admonitions.
- 0.625rem: code blocks and code tab bars.
- 0.75rem (
--pm-radius): cards, pagination, callouts. - Circles only for step markers and diagram nodes.
Primary: link-purple fill, --pm-on-primary text (white in light, page navy in dark), 0.5rem radius, 700 weight. Secondary: transparent with a --pm-border-strong edge and --pm-text. Both show the token focus ring.
- Doc cards (category indexes,
DocCardList): surface-1 panel, hairline border that turns purple on hover, a small tinted icon chip and a title. - Home cards (
CardGrid): same panel language; the icon (or step number) sits beside the title in link purple, and the arrow sits in flow at the foot of the card. - Pagination: same panel, border-only hover.
- Next-step callout (
NextStepCallout): surface-1 panel with a--pm-border-strongedge and a Rajdhani label. No tint and no stripe, so it never reads as an admonition. - Element tiles (
ElementTile): preview image, title and description as one link.
- Navbar: section tabs in 14px/500 muted text; the active tab is link-purple over a 2px purple rule on the bar's bottom border.
- Sidebar: muted 14px/500 links; the active page is link-purple text on a 2px purple left rule (a position marker, not a card accent); nested lists hang off a 1px guide line;
category-as-headergroups are Rajdhani labels over a hairline. - TOC: "Contents" label, a 1px guide line, the active heading mirrors the sidebar; Edit this page and help links below.
- Breadcrumbs: 13px muted trail, current page in text colour at 600.
Blocks on --pm-code-bg with a hairline border and no shadow; a title bar one surface step up; highlighted lines get a 10-16% purple tint and a 2px inset purple rule. Language tabs (SDK CodeBlock and Elements CodeDropdown) share one strip: Rajdhani labels, active label in link purple over a 2px rule. Inline code is a borderless surface-3 chip.
A faint tint of the type's status colour over the page inside a 1px border of the same colour (28% alpha), an icon and a Rajdhani type label in the status colour, body copy in --pm-text. An author's own title (:::tip[Title]) is set in Manrope 700 in its written case instead of the label. Links inside stay link-purple and clear 4.5:1 on every tint.
A framed, horizontally scrollable block with a surface-2 header, hairline cell borders and surface-1 zebra rows. Tables with 15+ rows cap their height and keep a sticky header.
Coded React diagrams (DiagramFrame and friends): a 2px text-colour top rule and a Rajdhani label (the website's DiagramFrame voice), real text, and a one-sentence caption.
TimelineWrapper / TimelineStep: numbered circles on a vertical rail for long step-by-step guides. Drawn like the diagrams' stage nodes: a 1px --pm-border-strong rail and outlined circles with the number in --pm-text on the page colour (they were white on Tailwind orange-500, 2.80:1, with a fixed #a666f4 rail in both themes).
Text selection is a purple wash (--pm-selection, 16% light / 20% dark, chosen so selected link text still clears 4.5:1) under unchanged text colour. Focus is always the token ring. Scrollbars in the sidebar and TOC stay transparent until hovered.
- Use
--pm-*tokens or the Infima variables mapped onto them; add a token (with its measured ratios) before adding a colour. - Target
ThemeClassNames, Infima andpm-*classes; restate upstream module styles on a stable class when you swizzle. - Keep motion to 120-180ms colour and border transitions (ease-out), and honour
prefers-reduced-motion. Hover never lifts or glows a card; the one movement is a 0.25rem nudge of an arrow on home cards and task links. - Check both themes at 1440px and 390px, and run
scripts/audit-a11y.mjs, before shipping a visual change.
- Don't select hashed CSS-module classes (
[class*=...]). - Don't draw a coloured side stripe thicker than 1px on a card, callout or admonition.
- Don't set sentences or custom titles in uppercase tracked Rajdhani.
- Don't add glow shadows, gradient text, or hover lifts to reading surfaces.
- Don't put body-size text on orange in light mode.