Navigation

RIM UI — Rebuild in Minimal

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.

v0.1.0 0 dependencies Pure CSS

Neo-Brutalist Design Style

Clean, sharp and structured design with bold edges and subtle textures every element has a purpose.

CSS Design

Design Tokens

All colors, spacing, typography and borders are defined as tokens are fully consistent and easy to customize.

CSS Tokens Variables

Semantic HTML First

All default elements are styled automatically. Write semantic HTML keeping markup clean and meaningful.

HTML Semantic

Themes

Built-in light and dark themes. Switch easily without adding extra CSS or breaking layout.

Themes Dark Mode Light Mode

Why I Build This?

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.

Getting Started

Three steps. No npm. No configuration. No build tools.

1. Add RIM CSS

<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">

2. Add Fonts (recommended)

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">

3. Set Theme

<html lang="en" data-theme="light">

Complete Starter

<!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.

Design Tokens

Every visual decision in RIM CSS is a CSS custom property. Override any token to customize the library.

Colors

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

Typography

Token Value Purpose
--rim-font-heading Space Grotesk Headings
--rim-font-body Inter Body text
--rim-font-code Fira Code Code elements

Spacing Scale

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

Typography

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.

Heading 1 The poster

Heading 2 The chapter

Heading 3 The section

Heading 4 The subsection

Heading 5 The detail
Heading 6

This is a paragraph

  • unordered list 1
  • unordered list 2
    • Nested items work too
    • Hierarchy is maintained
  • Everything is the design
  1. ordered list 1
  2. ordered list 2
  3. Ship it

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

Inline Code

Set data-theme="dark" on your <html> element.

Keyboard

Press Ctrl + Shift + P to open palette.

<kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>P</kbd>

Small & Abbreviation

Small text for captions.

The RIM library. Hover the abbreviation.

Button

Sharp corners. Hard shadow on hover. Pushes down on click. Disabled buttons get a strikethrough because cancelled means cancelled.

Variants

<button>Default</button>
<button data-variant="primary">Primary</button>
<button data-variant="accent">Accent</button>
<button disabled>Disabled</button>

Sizes

<button data-size="sm">Small</button>
<button>Default</button>
<button data-size="lg">Large</button>

Link as Button

Links can look like buttons using data-is="button". Same styles. Same variants. Use aria-disabled="true" for disabled links.

Link Default Link Primary Link Accent Link Disabled
<a data-is="button" href="#">Link Default</a>
<a data-is="button" data-variant="primary" href="#">Link Primary</a>
<a data-is="button" aria-disabled="true">Link Disabled</a>

Accessibility note: Links use aria-disabled="true" instead of disabled because the disabled attribute is not valid on <a> elements.

Callout / Alert

Important information that needs attention. Left border signals the type. Background tint gives context without screaming.

All Available Variants

Default. General information.

Info. Helpful context.

Warning. Be aware.

Success. All good.

Error. Something broke.

Default

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>

Info

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>

Warning

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>

Success

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>

Error

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>

Card

Content container. Sharp borders. Lifts on hover with hard shadow.

Basic Card

Design Tokens

Every visual decision lives as a CSS variable.

CSS

Zero Dependencies

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>
Note: You have to wrap with <div>when you want to add button or tags in card

Card with Image

Card image

Card with Image

Description for the card:

Tutorial CSS
<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>

Code Block Enhanced

Wraps <pre><code> with an optional filename label. The label sits on top like a terminal tab. Fira Code font. Scrollable for long lines.

Without Label

A clean code block with no header.

const philosophy = " Every element earns its place"; console.log(`rim`);
                        

With Filename Label

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.

Divider

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.

Default Divider

Clean horizontal line with generous margin.

Content above the divider. The line creates a clear visual break.


<hr data-is="divider">

Decorative 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">

Forms

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>

Tags

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.

Default Tags

CSS HTML JavaScript Design Minimal
<span data-is="tag">CSS</span>
<span data-is="tag">HTML</span>
<span data-is="tag">JavaScript</span>

Accent Variant

New Featured v0.1
<span data-is="tag" data-variant="accent">New</span>
<span data-is="tag" data-variant="accent">Featured</span>

Tags in Context

Tags are easy to use with card but remember you have to wrap it with the div.

Building RIM CSS

Minimal CSS Library

Tutorial CSS New

Tables

With semantic structure we can get clean minimal table.

Browser support
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>

Table of Contents

Navigation for long-form content. Shows document structure at a glance. Supports active state and nested sections.

Basic TOC

<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>

Nested TOC

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.

Container

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>

Stack

Vertical spacing between children. No margin hacks. The stack owns the gaps.

Default

Child 1 — 24px gap
Child 2
Child 3

Small

Child 1 — 12px gap
Child 2
Child 3

Large

Child 1 — 48px gap
Child 2
<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 -->

Grid

Responsive grid. Auto-fit by default. Force columns when needed.

Auto-fit (default)

1
2
3
4

2 Columns

Column 1
Column 2

3 Columns

1
2
3
<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.

Customization

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.

Override Design Tokens

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;
}

Override Dark Mode Separately

/* Custom dark mode */
[data-theme="dark"] {
  --rim-accent: #f472b6;
  --rim-accent-hover: #ec4899;
  --rim-bg: #0a0a0a;
  --rim-surface: #171717;
  --rim-border: #2a2a2a;
}

Override Specific Components

/* 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;
}

How @layer Works

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.

Available Tokens Reference

Color Tokens
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
Typography Tokens
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
Spacing Tokens
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
Border, Shadow & Layout Tokens
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

Complete API Reference

Every data attribute, variant and modifier in RIM CSS at a glance.

Core Attributes

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)

Layout Attributes

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 Attributes

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"

State Attributes

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)