Design Tokens
Every visual decision lives as a CSS variable.
RIM is a CSS library where every element has a purpose. No dependencies, No build tools, Write in semantic HTML, looks great and ships fast.
Clean, sharp and structured design with bold edges and subtle textures every element has a purpose.
All colors, spacing, typography and borders are defined as tokens are fully consistent and easy to customize.
All default elements are styled automatically. Write semantic HTML keeping markup clean and meaningful.
Built-in light and dark themes. Switch easily without adding extra CSS or breaking layout.
This was built to make website creation fast, easy and simple with clean and professional touch of neo-brutalist minimalism. Most of the styling is already done, so I don’t need to write CSS for basic elements. I only add custom styles when necessary. Semantic HTML works out of the box giving me a solid structured foundation along with full flexibility.
Three steps. No npm. No configuration. No build tools.
<link rel="stylesheet" href="path/to/rim.css">
Or use a CDN from GitHub:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/ronish-maharjan/[email protected]/dist/rim.min.css">
RIM CSS works without these fonts using system fallbacks.
But for the full experience, add this to your
<head>:
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Fira+Code:[email protected]&family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=Space+Grotesk:[email protected]&display=swap" rel="stylesheet">
<html lang="en" data-theme="light">
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Site</title>
<link rel="stylesheet" href="rim.css">
</head>
<body>
<div data-is="container-reading">
<div data-is="stack">
<h1>Hello, RIM.</h1>
<p>CSS that earns its place.</p>
</div>
</div>
</body>
</html>
That's it. No configuration files. No JavaScript imports. No package manager. Just HTML and CSS.
Every visual decision in RIM CSS is a CSS custom property. Override any token to customize the library.
| Token | Light | Dark | Purpose |
|---|---|---|---|
--rim-bg |
#f4f5f7 | #000000 | Page background |
--rim-text |
#000000 | #ffffff | Primary text |
--rim-accent |
#b45309 | #22c55e | Accent color |
--rim-muted |
#6b7280 | #9ca3af | Secondary text |
--rim-border |
#000000 | #333333 | Border color |
--rim-surface |
#ffffff | #111111 | Card/input backgrounds |
--rim-code-bg |
#e9ebef | #1a1a1a | Code backgrounds |
| Token | Value | Purpose |
|---|---|---|
--rim-font-heading |
Space Grotesk | Headings |
--rim-font-body |
Inter | Body text |
--rim-font-code |
Fira Code | Code elements |
| Token | Value | Pixels |
|---|---|---|
--rim-space-1 |
0.25rem | 4px |
--rim-space-2 |
0.5rem | 8px |
--rim-space-3 |
0.75rem | 12px |
--rim-space-4 |
1rem | 16px |
--rim-space-5 |
1.5rem | 24px |
--rim-space-6 |
2rem | 32px |
--rim-space-7 |
3rem | 48px |
--rim-space-8 |
4rem | 64px |
Headings use Space Grotesk.Body uses Inter and other code stuffs uses FiraCode. I choosed this fonts because i love it you can change your fonts by editing the token.
This is a paragraph
This is a link that goes somewhere. Underline pulls closer on hover.
Strong text and emphasized text.
You can highlight important text with the mark element.
<mark>highlighted text</mark>
The details are not the details. They make the design.
Charles Eames
Set data-theme="dark" on your <html> element.
Press Ctrl + Shift + P to open palette.
<kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>P</kbd>
Small text for captions.
The RIM library. Hover the abbreviation.
Important information that needs attention. Left border signals the type. Background tint gives context without screaming.
Default. General information.
Info. Helpful context.
Warning. Be aware.
Success. All good.
Error. Something broke.
Note. This is a default callout for general information without a specific type.
<div data-is="callout">
<p><strong>Note.</strong> General information.</p>
</div>
Helpful context, tips, and supplementary information.
Info.
RIM CSS uses @layer for cascade control.
Your custom CSS always wins over library styles.
<div data-is="callout" data-variant="info">
<p><strong>Info.</strong> Helpful context here.</p>
</div>
Something to be careful about.
Warning. This library requires a modern browser. Internet Explorer is not supported.
<div data-is="callout" data-variant="warning">
<p><strong>Warning.</strong> Be careful about this.</p>
</div>
Confirmation and positive outcomes.
Success. Your site is now using RIM CSS. Every element has DNA.
<div data-is="callout" data-variant="success">
<p><strong>Success.</strong> Positive confirmation.</p>
</div>
Something went wrong. Critical information.
Error. Something went wrong. But at least it looks good while failing.
<div data-is="callout" data-variant="error">
<p><strong>Error.</strong> Something went wrong.</p>
</div>
Content container. Sharp borders. Lifts on hover with hard shadow.
Every visual decision lives as a CSS variable.
No npm. No build tools. Pure CSS.
<article data-is="card">
<h4>Design Tokens</h4>
<p>Every visual decision lives as a CSS variable.</p>
<div>
<span data-is="tag">CSS</span>
</div>
</article>
<div>when you want to add button or tags in card
Description for the card:
<article data-is="card">
<img src="image.jpg" alt="...">
<h4>Card with Image</h4>
<p>First image becomes the card header.</p>
<div>
<span data-is="tag">Tutorial</span>
</div>
</article>
Wraps <pre><code> with an optional
filename label. The label sits on top like a terminal tab.
Fira Code font. Scrollable for long lines.
A clean code block with no header.
const philosophy = " Every element earns its place"; console.log(`rim`);
Add data-label to show a filename header.
Great for tutorials and documentation.
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
<link rel="stylesheet" href="rim.css">
</head>
<body>
<h1>Hello, RIM.</h1>
</body>
</html>
The label is generated from the data-label
attribute using CSS ::before pseudo-element.
No JavaScript needed.
Section separator with more presence than a plain
<hr>. Default is a clean line.
Decorative adds an editorial pause — like a scene
break in a novel.
Clean horizontal line with generous margin.
Content above the divider. The line creates a clear visual break.
<hr data-is="divider">
So i havent think of good decorative divider but you can add your own divider my changing the text.
<hr data-is="divider" data-variant="decorative">
Built on native <details> +
<summary>. Zero JavaScript required.
Keyboard accessible. Screen reader friendly. Three patterns:
content reveal, accordion group and action menu.
Expandable content sections. Click to open, click to close. FAQ, collapsible panels, spoiler text.
RIM CSS is a minimal CSS library built on the philosophy of Raw Intentional Minimal. Every element, every component, every byte earns its place.
Yes. Override any --rim-* CSS variable in
your own stylesheet. Your CSS always wins over RIM's
@layer system.
<details data-is="dropdown">
<summary>What is RIM CSS?</summary>
<div>
<p>A minimal CSS library where every element earns its place.</p>
</div>
</details>
Add the native open attribute to show
content by default.
This content is visible immediately. The user can close it by clicking the summary.
<details data-is="dropdown" open>
<summary>This one starts open</summary>
<div><p>Visible by default.</p></div>
</details>
Stack dropdowns together with shared borders. Looks like a unified accordion. Multiple items can be open simultaneously.
Add one line to your HTML <head>
and you're ready. No npm, no build tools, no
configuration files.
Optionally add the Google Fonts link for Space Grotesk, Inter, and Fira Code. RIM CSS works without them using system font fallbacks.
Add data-theme="light" or
data-theme="dark" to your
<html> element.
Write semantic HTML. Use data-is
attributes for components. That's the entire API.
Your site has DNA now.
<div data-is="dropdown-group">
<details data-is="dropdown">
<summary>Step 1 — Install</summary>
<div><p>Add one line to your HTML.</p></div>
</details>
<details data-is="dropdown">
<summary>Step 2 — Add Fonts</summary>
<div><p>Optional Google Fonts link.</p></div>
</details>
<details data-is="dropdown">
<summary>Step 3 — Ship It</summary>
<div><p>Your site has DNA now.</p></div>
</details>
</div>
Dropdown groups share borders between items — no double lines. They look like one cohesive unit.
Action menu that positions below the trigger. The trigger looks and behaves like a button hard shadow on hover, push-down on click.
<details data-is="dropdown" data-variant="menu">
<summary>Actions</summary>
<ul>
<li><a href="#">Edit post</a></li>
<li><a href="#">Duplicate</a></li>
<li><a href="#">Share</a></li>
<li><hr></li>
<li><a href="#" data-danger>Delete</a></li>
</ul>
</details>
| Feature | How | What it does |
|---|---|---|
| Separator | <li><hr></li> |
Visual divider between menu groups |
| Danger item | data-danger |
Red text for destructive actions (delete, remove) |
| Auto-close | JS click handler | Close menu when clicking outside (see Themes section) |
Note: The menu dropdown uses native
<details> behavior. It opens and closes
on click without JavaScript. For closing when clicking outside
General minimal form that works for basic purpose.
<form>
<label for="name">Name</label>
<input type="text" id="name" placeholder="Enter your name">
<label for="msg">Message</label>
<textarea id="msg" rows="3"></textarea>
<label for="role">Role</label>
<select id="role">
<option>Developer</option>
<option>Designer</option>
</select>
</form>
I found tags are very helpfull for quickly giving context information. Thats why i created tag component. A Small labels for categories, topics and status.
<span data-is="tag">CSS</span>
<span data-is="tag">HTML</span>
<span data-is="tag">JavaScript</span>
<span data-is="tag" data-variant="accent">New</span>
<span data-is="tag" data-variant="accent">Featured</span>
Tags are easy to use with card but remember you have to wrap it with the div.
Minimal CSS Library
With semantic structure we can get clean minimal table.
| Browser | Version | Status |
|---|---|---|
| Chrome | 100+ | ✅ Supported |
| Firefox | 100+ | ✅ Supported |
| Safari | 16+ | ✅ Supported |
<table>
<caption>Browser support</caption>
<thead>
<tr>
<th>Browser</th>
<th>Version</th>
</tr>
</thead>
<tbody>
<tr>
<td>Chrome</td>
<td>100+</td>
</tr>
</tbody>
</table>
Navigation for long-form content. Shows document structure at a glance. Supports active state and nested sections.
<nav data-is="toc">
<h4>On This Page</h4>
<ol>
<li><a href="#intro" aria-current="true">Introduction</a></li>
<li><a href="#philosophy">The Philosophy</a></li>
<li><a href="#start">Getting Started</a></li>
<li><a href="#components">Components</a></li>
<li><a href="#custom">Customization</a></li>
</ol>
</nav>
Sub-sections use alphabetical numbering automatically.
<nav data-is="toc">
<h4>Contents</h4>
<ol>
<li><a href="#intro">Introduction</a></li>
<li><a href="#philosophy">Philosophy</a>
<ol>
<li><a href="#beliefs">Core beliefs</a></li>
<li><a href="#principles">Design principles</a></li>
</ol>
</li>
<li><a href="#start">Getting Started</a></li>
</ol>
</nav>
Mark the currently active section with
aria-current="true". The link becomes
accent-colored and bold. To update it dynamically
as the user scrolls, use a small Intersection Observer script.
Controls content width and centers it. RIM container have three variants.
| Attribute | Max Width | Use Case |
|---|---|---|
data-is="container" |
1080px | Page layouts, grids, cards |
data-is="container-reading" |
680px | Blog posts, long-form text |
data-is="container-full" |
100% | Edge to edge content |
<!-- Page width -->
<div data-is="container">...</div>
<!-- Reading width (blog posts) -->
<div data-is="container-reading">...</div>
<!-- Full width -->
<div data-is="container-full">...</div>
Vertical spacing between children. No margin hacks. The stack owns the gaps.
<div data-is="stack">...</div> <!-- default 24px -->
<div data-is="stack" data-gap="sm">...</div> <!-- tight 12px -->
<div data-is="stack" data-gap="lg">...</div> <!-- generous 48px -->
Responsive grid. Auto-fit by default. Force columns when needed.
<div data-is="grid">...</div> <!-- auto-fit -->
<div data-is="grid" data-cols="2">...</div> <!-- 2 columns -->
<div data-is="grid" data-cols="3">...</div> <!-- 3 columns -->
All grids collapse to single column on mobile automatically. No media queries needed.
RIM CSS uses @layer. Your CSS is unlayered,
which means it always wins over RIM's
styles. No !important hacks. No specificity
wars. Just write CSS it overrides automatically.
Change any variable to transform the entire library.
/* Your custom theme */
:root {
/* Change accent color */
--rim-accent: #e11d48;
--rim-accent-hover: #be123c;
/* Change fonts */
--rim-font-heading: 'Georgia', serif;
--rim-font-body: 'Merriweather', serif;
/* Add rounded corners (override sharp default) */
--rim-radius: 6px;
/* Change background */
--rim-bg: #fefce8;
/* Change spacing feel */
--rim-space-5: 2rem;
--rim-space-7: 4rem;
}
/* Custom dark mode */
[data-theme="dark"] {
--rim-accent: #f472b6;
--rim-accent-hover: #ec4899;
--rim-bg: #0a0a0a;
--rim-surface: #171717;
--rim-border: #2a2a2a;
}
/* Cards always have subtle shadow */
[data-is="card"] {
box-shadow: var(--rim-shadow-sm);
}
/* Thicker callout border */
[data-is="callout"] {
border-left-width: 4px;
}
/* Custom primary button */
button[data-variant="primary"] {
background-color: hotpink;
border-color: hotpink;
}
/* Bigger tags */
[data-is="tag"] {
padding: var(--rim-space-2) var(--rim-space-4);
font-size: var(--rim-text-sm);
}
/* Remove background texture */
body {
background-image: none;
}
RIM CSS declares all its styles inside named layers. CSS outside any layer has higher priority than layered CSS. Since your stylesheet is not inside a layer, it always wins.
@layer rim-reset, /* Browser normalization — lowest priority */
rim-tokens, /* Design variables */
rim-base, /* Typography & elements */
rim-layout, /* Container, stack, grid */
rim-components, /* Buttons, cards, etc */
rim-utilities; /* Helpers — highest RIM priority */
/* ↑ All RIM styles live inside these layers */
/* ↓ Your CSS lives OUTSIDE layers always wins */
Practical result: You never need
!important. You never need to match
RIM's selector specificity. Just write a normal CSS
rule targeting the same element and your style applies.
| Token | Purpose |
|---|---|
--rim-bg |
Page background |
--rim-text |
Primary text color |
--rim-accent |
Accent / brand color |
--rim-accent-hover |
Accent hover state |
--rim-muted |
Secondary text |
--rim-border |
Border color |
--rim-surface |
Card/input backgrounds |
--rim-code-bg |
Code backgrounds |
--rim-highlight |
Mark element background |
--rim-info |
Info callout color |
--rim-warning |
Warning callout color |
--rim-success |
Success callout color |
--rim-error |
Error callout color |
--rim-selection-bg |
Text selection background |
--rim-selection-text |
Text selection color |
| Token | Purpose |
|---|---|
--rim-font-heading |
Heading font family |
--rim-font-body |
Body font family |
--rim-font-code |
Code font family |
--rim-text-h1 to --rim-text-h6 |
Heading sizes |
--rim-text-base |
Body text size |
--rim-text-sm |
Small text |
--rim-text-xs |
Extra small text |
--rim-text-lg |
Large text |
--rim-weight-normal |
400 weight |
--rim-weight-medium |
600 weight |
--rim-weight-bold |
700 weight |
--rim-leading-tight |
Heading line height |
--rim-leading-normal |
Body line height |
| Token | Value | Pixels |
|---|---|---|
--rim-space-1 |
0.25rem | 4px |
--rim-space-2 |
0.5rem | 8px |
--rim-space-3 |
0.75rem | 12px |
--rim-space-4 |
1rem | 16px |
--rim-space-5 |
1.5rem | 24px |
--rim-space-6 |
2rem | 32px |
--rim-space-7 |
3rem | 48px |
--rim-space-8 |
4rem | 64px |
--rim-space-9 |
6rem | 96px |
--rim-space-10 |
8rem | 128px |
| Token | Purpose |
|---|---|
--rim-border-width |
Border width (1px) |
--rim-border-style |
Border style (solid) |
--rim-radius |
Border radius (0px) |
--rim-shadow-sm |
Small shadow |
--rim-shadow-md |
Medium shadow |
--rim-shadow-hard |
Hard offset shadow |
--rim-width-reading |
Reading container (680px) |
--rim-width-page |
Page container (1080px) |
--rim-transition |
Default transition |
--rim-transition-fast |
Fast transition |
--rim-transition-slow |
Slow transition |
Every data attribute, variant and modifier in RIM CSS at a glance.
| Attribute | Values | Purpose |
|---|---|---|
data-theme |
light dark |
Set theme (on <html>) |
data-is |
see component list | Declare what an element IS |
data-variant |
see variant list | Which version of a component |
data-size |
sm lg |
Size override (default is medium) |
| Attribute | Values | Used On |
|---|---|---|
data-is="container" |
— | 1080px centered wrapper |
data-is="container-reading" |
— | 680px reading wrapper |
data-is="container-full" |
— | 100% width wrapper |
data-is="stack" |
— | Vertical spacing |
data-gap |
sm lg |
Stack gap size |
data-is="grid" |
— | Responsive grid |
data-cols |
2 3 |
Force grid columns |
| Component | Attribute | Variants |
|---|---|---|
| Button | auto-styled | primary accent + disabled |
| Link as Button | data-is="button" |
primary accent + aria-disabled |
| Card | data-is="card" |
— |
| Tag | data-is="tag" |
accent |
| Callout | data-is="callout" |
info warning success error
|
| Code Block | data-is="codeblock" |
data-label="filename" |
| Breadcrumb | data-is="breadcrumb" |
aria-current="page" |
| TOC | data-is="toc" |
aria-current="true" |
| Divider | data-is="divider" |
decorative |
| Dropdown | data-is="dropdown" |
menu |
| Dropdown Group | data-is="dropdown-group" |
— |
| Attribute | Type | Used For |
|---|---|---|
disabled |
Native HTML | Disabled buttons (strikethrough text) |
aria-disabled="true" |
ARIA | Disabled links styled as buttons |
aria-current="page" |
ARIA | Current page in breadcrumb |
aria-current="true" |
ARIA | Active item in TOC |
open |
Native HTML | Pre-opened dropdown |
data-danger |
Custom | Destructive menu items (red) |