npm package: @sharvibelsare/setcss
Description: POC: runtime set-* utility classes mapped to inline styles in the browser (no build step).
Author: Sharvi Belsare
Latest version: 0.1.1

# SetCSS

SetCSS is a small **runtime utility “engine”** for the browser: you add classes prefixed with `set-` to your HTML, and a script walks the DOM on `DOMContentLoaded`, turning each recognized class into **inline styles** (and optionally injecting icon markup). There is no build step and no generated CSS file—utilities live in plain JavaScript modules you can edit or extend.

**This project is a proof of concept (POC)**—an experiment to explore class-to-style mapping in the browser, not a supported product or production-ready framework. APIs, behavior, and structure may change without notice.

---

## When to use it

- Quick prototypes, demos, or internal tools where you want **utility-style** markup without a CSS pipeline.
- Learning how class names can map to style objects in JS.

For production sites, most teams will prefer a static CSS approach (or a mature utility framework). SetCSS is intentionally minimal and **POC-level** only.

---

## Quick start

### 1. Markup

Use classes that start with `set-`:

```html
<div
  class="set-flex set-gap-16 set-p-20 set-bg-white set-border-2 set-border-black"
>
  <span class="set-font-bold set-text-16">Hello</span>
</div>
```

### 2. Load the script

**Option A — ES modules (needs a local server)**

Browsers block ES modules on `file://`. Serve the folder over HTTP and use:

```html
<script type="module" src="main.js"></script>
```

`main.js` imports `styles.js`, which applies utilities once the document is ready.

**Option B — Single bundle (works with `file://`)**

For opening `index.html` directly from disk, use the bundled script (no `import` / `export`):

```html
<script src="SetCSS.bundle.js" defer></script>
```

Keep the bundle in sync if you change the modules (or add a small build step later).

### 3. Optional: fonts and icons

- **Fonts:** Link any faces you reference with `set-font-*` (e.g. Inter, Poppins, Roboto) in your HTML.
- **Icons:** `set-icon-{name}` expects **Font Awesome 6** (`fa-solid fa-{name}`). Include the FA stylesheet; icon names must be a **single** segment after `set-icon-` (use `envelope`, not `paper-plane`).

---

## Install from npm

```bash
npm install SetCSS
```

The package is **ESM-only** (`"type": "module"`). Use it in the browser with a bundler or native modules over HTTP:

```js
import applyStyles from "SetCSS";
// or: import { applyStyles } from "SetCSS";

document.addEventListener("DOMContentLoaded", () => {
  applyStyles();
});
```

**CDN (no install):** after you publish, the bundle is exposed as `SetCSS/bundle` on CDNs such as [jsDelivr](https://www.jsdelivr.com/) or [unpkg](https://unpkg.com/):

```html
<script
  src="https://cdn.jsdelivr.net/npm/SetCSS@0.1.0/SetCSS.bundle.js"
  defer
></script>
```

---

## How it works

1. On `DOMContentLoaded`, `applyStyles()` runs (`styles.js` / bundle).
2. Every element is visited; each class in `element.classList` is checked.
3. Classes **not** starting with `set-` are ignored.
4. For each `set-*` class, resolvers run in this order until one returns a style object: **Colors → Spacing → Typography → Fonts → Layout → Box model → Shadow**.
5. If a style object is returned, its properties are merged with `Object.assign(element.style, …)`.
6. **Icons** are handled separately: matching `set-icon-*` prepends an `<i>` child if one is not already there.

If two classes set the same CSS property, **whichever is processed later in your `classList` order wins** for that property (browser-dependent ordering; avoid conflicting utilities on the same node when possible).

---

## Utility reference

All numeric tokens below are **pixels** (e.g. `set-p-16` → `padding: 16px`).

### Colors (`colors.js`)

| Pattern                     | Effect                                                                                   |
| --------------------------- | ---------------------------------------------------------------------------------------- |
| `set-color-{name}`          | `color`                                                                                  |
| `set-bg-{name}`             | `background-color`                                                                       |
| `set-border-{name}`         | `border-color` (when `{name}` is not a number)                                           |
| `set-border-{n}`            | `border-width: npx`, `border-style: solid` (when `{n}` is numeric)                       |
| `set-{type}-{name}-{shade}` | Optional numeric `shade` adjusts the computed RGB (`type` is `color`, `bg`, or `border`) |

`{name}` must be a **single hyphen-free token** that the browser understands as a color (e.g. `red`, `coral`, `dimgrey`, `black`). **Avoid** names like `dimgray`: the class is split on `-`, so the parser treats them as multiple parts. Prefer `dimgrey` or another one-word name.

Combine border **width** and **color** with two classes, e.g. `set-border-2 set-border-black`.

### Spacing (`spacing.js`)

| Class                                                  | Property                         |
| ------------------------------------------------------ | -------------------------------- |
| `set-m-{n}`                                            | `margin`                         |
| `set-mt-{n}`, `set-mb-{n}`, `set-ml-{n}`, `set-mr-{n}` | Side margins                     |
| `set-mx-{n}`                                           | `margin-left` + `margin-right`   |
| `set-my-{n}`                                           | `margin-top` + `margin-bottom`   |
| `set-p-{n}`                                            | `padding`                        |
| `set-pt-{n}`, `set-pb-{n}`, `set-pl-{n}`, `set-pr-{n}` | Side padding                     |
| `set-px-{n}`                                           | `padding-left` + `padding-right` |
| `set-py-{n}`                                           | `padding-top` + `padding-bottom` |

`{n}` must be numeric (`set-p-10` works; `set-p-auto` does not).

### Typography (`typography.js`)

| Class                                                               | Effect                                                                |
| ------------------------------------------------------------------- | --------------------------------------------------------------------- |
| `set-title`, `set-subtitle`, `set-body`, `set-caption`, `set-label` | Preset font size, weight, line height (see `typographyMap` in source) |
| `set-text-{n}`                                                      | `font-size: npx`                                                      |
| `set-font-bold`                                                     | `font-weight: 700`                                                    |
| `set-text-center` / `set-text-start` / `set-text-end`               | `text-align`                                                          |

### Fonts (`fonts.js`)

`set-font-{key}` where `{key}` is one of: `Inter`, `Roboto`, `Poppins`, `mono`, `sans`, `serif`.  
Load the actual webfonts in HTML if you use Inter / Roboto / Poppins.

### Layout (`layout.js`)

| Class                | Effect                                             |
| -------------------- | -------------------------------------------------- |
| `set-flex`           | `display: flex`                                    |
| `set-flex-col`       | `flex-direction: column` (use **with** `set-flex`) |
| `set-justify-center` | `justify-content: center`                          |
| `set-items-center`   | `align-items: center`                              |
| `set-center`         | flex + center + center (shortcut)                  |
| `set-gap-{n}`        | `gap: npx`                                         |

There is **no** `justify-between`, `flex-wrap`, etc.—add those with normal CSS if you need them.

### Box model (`box-model.js`)

| Class             | Effect               |
| ----------------- | -------------------- |
| `set-w-{n}`       | `width: npx`         |
| `set-h-{n}`       | `height: npx`        |
| `set-rounded-{n}` | `border-radius: npx` |

No percentage or `max-width` utilities—use plain CSS for those.

### Shadow (`shadow.js`)

| Class             | Effect                                                |
| ----------------- | ----------------------------------------------------- |
| `set-shadow`      | Soft shadow                                           |
| `set-shadow-hard` | Offset solid “neubrutalist” shadow (`6px 6px 0 #000`) |

### Icons (`icon.js`)

| Class             | Effect                                        |
| ----------------- | --------------------------------------------- |
| `set-icon-{name}` | Prepends `<i class="fa-solid fa-{name}"></i>` |

`{name}` is only **one** segment (`set-icon-star` → `fa-star`). For multi-word Font Awesome icons, extend `icon.js` or use HTML icons manually.

---

## Project layout

| File                                                                                                        | Role                                                            |
| ----------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- |
| `main.js`                                                                                                   | Entry for ES modules; runs `applyStyles` on `DOMContentLoaded`. |
| `styles.js`                                                                                                 | Wires resolvers together.                                       |
| `colors.js`, `spacing.js`, `typography.js`, `fonts.js`, `layout.js`, `box-model.js`, `shadow.js`, `icon.js` | One concern per file; add or edit parsers here.                 |
| `SetCSS.bundle.js`                                                                                          | Single-file build for `file://` or non-module pages.            |
| `index.html`                                                                                                | Demo UI using the utilities.                                    |

---

## Extending SetCSS

1. Add a branch or new `if` in the right module (e.g. new shadow token in `shadow.js`).
2. If you add a new module, import it in `styles.js` and include it in the `Colors || Spacing || …` chain (order matters for overlapping patterns).
3. Mirror changes in `SetCSS.bundle.js` if you rely on the bundle.

---

## Limitations (good to know up front)

- **POC scope:** Expect rough edges, incomplete utilities, and no stability guarantees—this repo is for exploration and demos.
- **Performance:** Full `querySelectorAll("*")` and per-class parsing on every run; fine for small pages, not tuned for huge SPAs.
- **No re-run:** If you inject new DOM later, call `applyStyles()` again yourself (export it or duplicate a public API).
- **Parsing:** Splitting on `-` limits color names and icon names as described above.
- **Coverage:** Many CSS features are intentionally missing; pair SetCSS with a small `<style>` block for `box-sizing`, `flex-wrap`, `max-width`, form resets, etc., as in the demo.

---