<p align="center">
  <img src="essential-cursor-logo.png" alt="Essential Cursor Logo" width="250">
</p>

<h1 align="center">Essential Cursor</h1>

<p align="center">
  <strong>41 Pointers. One Grid. Zero JavaScript.</strong>
</p>

<p align="center">
  The ultimate pure CSS SVG cursor library. CDN-ready, fully themeable, and strictly WCAG 2.2 compliant.
</p>

<p align="center">
  <em>Part of the <strong>Essential Web Tools</strong> ecosystem. Building the foundational layers of the modern web.</em>
</p>

<p align="center">
  <a href="https://www.npmjs.com/package/essential-cursors"><img src="https://img.shields.io/npm/v/essential-cursors.svg?style=flat-square" alt="npm version"></a>
  <a href="https://opensource.org/licenses/BSD-3-Clause"><img src="https://img.shields.io/badge/license-BSD--3--Clause-blue.svg?style=flat-square" alt="license BSD-3-Clause"></a>
  <a href="https://bundlephobia.com/package/essential-cursors"><img src="https://img.shields.io/bundlephobia/minzip/essential-cursors?style=flat-square&label=gzip" alt="gzip size"></a>
  <a href="https://github.com/essential-web-tools/essential-cursor/actions/workflows/ci.yml"><img src="https://github.com/essential-web-tools/essential-cursor/actions/workflows/ci.yml/badge.svg" alt="ci"></a>
  <a href="https://www.jsdelivr.com/package/npm/essential-cursors"><img src="https://data.jsdelivr.com/v1/package/npm/essential-cursors/badge?style=flat-square" alt="jsDelivr"></a>
  <a href="#-ai-context"><img src="https://img.shields.io/badge/AI-Ready-black?style=flat-square&logo=openai" alt="AI Ready"></a>
</p>

---

## 🚀 Why Essential Cursor?

Stop settling for default, ugly, or inaccessible system cursors. **Essential Cursor** brings 41 beautifully crafted, pixel-perfect SVG cursors to your web application using **pure CSS**. 

No JavaScript. No heavy bundles. No layout shifts. Just drop in a single CSS file and get instant access to a professional, accessible, and highly customizable cursor ecosystem.

✨ **Key Features:**
- 🎨 **41 Pixel-Perfect SVGs:** From standard pointers to complex resize and rotation tools.
- ⚡ **Zero JavaScript:** Blazing fast, pure CSS implementation.
- 🌗 **Auto Dark/Light Mode:** Seamlessly adapts to user preferences.
- ♿ **WCAG 2.2 Compliant:** Built with accessibility at its core (High contrast, target sizes, reduced motion).
- 📦 **Microscopic Footprint:** Under 6KB gzipped.
- 🤖 **AI-Ready:** Explicit context for LLMs to generate perfect code.

---

## 🖱️ Grouped Gallery

### Selection & Pointers

<table>
<tr>
  <td align="center"><img src="src/svg/default.svg" width="48" alt="Default cursor"><br><code>default</code></td>
  <td align="center"><img src="src/svg/pointer.svg" width="48" alt="Pointer cursor"><br><code>pointer</code></td>
  <td align="center"><img src="src/svg/click.svg" width="48" alt="Click cursor"><br><code>click</code></td>
  <td align="center"><img src="src/svg/crosshair.svg" width="48" alt="Crosshair cursor"><br><code>crosshair</code></td>
  <td align="center"><img src="src/svg/text.svg" width="48" alt="Text cursor"><br><code>text</code></td>
  <td align="center"><img src="src/svg/text-select.svg" width="48" alt="Text select cursor"><br><code>text-select</code></td>
</tr>
<tr>
  <td align="center"><img src="src/svg/not-allowed.svg" width="48" alt="Not allowed cursor"><br><code>not-allowed</code></td>
  <td align="center"><img src="src/svg/help.svg" width="48" alt="Help cursor"><br><code>help</code></td>
  <td align="center"><img src="src/svg/wait.svg" width="48" alt="Wait cursor"><br><code>wait</code></td>
  <td align="center"><img src="src/svg/eyedropper.svg" width="48" alt="Eyedropper cursor"><br><code>eyedropper</code></td>
  <td align="center"><img src="src/svg/location-pin.svg" width="48" alt="Location pin cursor"><br><code>location-pin</code></td>
</tr>
</table>

### Hands & Rotation

<table>
<tr>
  <td align="center"><img src="src/svg/grab.svg" width="48" alt="Grab cursor"><br><code>grab</code></td>
  <td align="center"><img src="src/svg/grabbing.svg" width="48" alt="Grabbing cursor"><br><code>grabbing</code></td>
  <td align="center"><img src="src/svg/pan.svg" width="48" alt="Pan cursor"><br><code>pan</code></td>
  <td align="center"><img src="src/svg/hand-rotate.svg" width="48" alt="Hand rotate cursor"><br><code>hand-rotate</code></td>
  <td align="center"><img src="src/svg/rotate.svg" width="48" alt="Rotate cursor"><br><code>rotate</code></td>
</tr>
<tr>
  <td align="center"><img src="src/svg/rotate-object.svg" width="48" alt="Rotate object cursor"><br><code>rotate-object</code></td>
  <td align="center"><img src="src/svg/rotate-selection.svg" width="48" alt="Rotate selection cursor"><br><code>rotate-selection</code></td>
</tr>
</table>

### Resize

<table>
<tr>
  <td align="center"><img src="src/svg/n-resize.svg" width="48" alt="North resize cursor"><br><code>n-resize</code></td>
  <td align="center"><img src="src/svg/ne-resize.svg" width="48" alt="North-East resize cursor"><br><code>ne-resize</code></td>
  <td align="center"><img src="src/svg/e-resize.svg" width="48" alt="East resize cursor"><br><code>e-resize</code></td>
  <td align="center"><img src="src/svg/se-resize.svg" width="48" alt="South-East resize cursor"><br><code>se-resize</code></td>
  <td align="center"><img src="src/svg/s-resize.svg" width="48" alt="South resize cursor"><br><code>s-resize</code></td>
  <td align="center"><img src="src/svg/sw-resize.svg" width="48" alt="South-West resize cursor"><br><code>sw-resize</code></td>
</tr>
<tr>
  <td align="center"><img src="src/svg/w-resize.svg" width="48" alt="West resize cursor"><br><code>w-resize</code></td>
  <td align="center"><img src="src/svg/nw-resize.svg" width="48" alt="North-West resize cursor"><br><code>nw-resize</code></td>
  <td align="center"><img src="src/svg/ns-resize.svg" width="48" alt="North-South resize cursor"><br><code>ns-resize</code></td>
  <td align="center"><img src="src/svg/ew-resize.svg" width="48" alt="East-West resize cursor"><br><code>ew-resize</code></td>
  <td align="center"><img src="src/svg/nesw-resize.svg" width="48" alt="North-East South-West resize cursor"><br><code>nesw-resize</code></td>
  <td align="center"><img src="src/svg/nwse-resize.svg" width="48" alt="North-West South-East resize cursor"><br><code>nwse-resize</code></td>
</tr>
</table>

### Objects & Tools

<table>
<tr>
  <td align="center"><img src="src/svg/move.svg" width="48" alt="Move cursor"><br><code>move</code></td>
  <td align="center"><img src="src/svg/add.svg" width="48" alt="Add cursor"><br><code>add</code></td>
  <td align="center"><img src="src/svg/add-object.svg" width="48" alt="Add object cursor"><br><code>add-object</code></td>
  <td align="center"><img src="src/svg/copy-object.svg" width="48" alt="Copy object cursor"><br><code>copy-object</code></td>
  <td align="center"><img src="src/svg/duplicate-object.svg" width="48" alt="Duplicate object cursor"><br><code>duplicate-object</code></td>
</tr>
<tr>
  <td align="center"><img src="src/svg/pencil.svg" width="48" alt="Pencil cursor"><br><code>pencil</code></td>
  <td align="center"><img src="src/svg/pencil-add.svg" width="48" alt="Pencil add cursor"><br><code>pencil-add</code></td>
  <td align="center"><img src="src/svg/scale-object.svg" width="48" alt="Scale object cursor"><br><code>scale-object</code></td>
</tr>
</table>

### Zoom & Navigation

<table>
<tr>
  <td align="center"><img src="src/svg/zoom.svg" width="48" alt="Zoom cursor"><br><code>zoom</code></td>
  <td align="center"><img src="src/svg/zoom-in.svg" width="48" alt="Zoom in cursor"><br><code>zoom-in</code></td>
  <td align="center"><img src="src/svg/zoom-out.svg" width="48" alt="Zoom out cursor"><br><code>zoom-out</code></td>
</tr>
</table>

---

## ⚡ Installation

### jsDelivr (Recommended CDN)

```html
<!-- Pinned version with Subresource Integrity (SRI) -->
<link 
  rel="stylesheet" 
  href="https://cdn.jsdelivr.net/npm/essential-cursors@1.1.0/dist/essential-cursors.min.css"
  integrity="sha384-qQ60ujaappdzuW5KRSu9rFuVDwc034aCozapGOQoqsuhGJgx04b3Ai6V5uZ87Zp+"
  crossorigin="anonymous">
```

> 🔐 **Always use SRI in production.** Hashes are available in [`dist/integrity.json`](dist/integrity.json).

### unpkg

```html
<link rel="stylesheet" href="https://unpkg.com/essential-cursors@1.1.0/dist/essential-cursors.min.css">
```

### npm

```bash
npm install essential-cursors
```

```css
/* In your CSS bundle */
@import 'essential-cursors/dist/essential-cursors.css';
/* or */
@import 'essential-cursors';
```

---

## 🎯 Usage

### Mode 1: Utility Classes

```html
<button class="ec-pointer">Click here</button>
<div class="ec-grab">Drag this element</div>
<span class="ec-wait">Loading...</span>
```

### Mode 2: `data-cursor` Attribute

```html
<div data-cursor="zoom-in">Zoom in</div>
<div data-cursor="rotate">Rotate</div>
<div data-cursor="text-select">Select text</div>
```

### Mode 3: CSS Variables (Tokens)

```css
.element {
  cursor: var(--ec-pointer);
}

.zoomable {
  cursor: var(--ec-zoom-in);
}

.movable {
  cursor: var(--ec-move);
}
```

---

## 🤖 AI Context & Prompt Instructions

> **For LLMs and AI Agents:** This section provides exact context to help you generate correct implementation code for this library.

- **Library Name:** `essential-cursors`
- **Architecture:** Pure CSS (No JS runtime required).
- **Core Mechanism:** Maps CSS variables (`--ec-*`) to data-URIs containing SVG cursors, with native CSS `cursor` keywords as mandatory fallbacks.
- **How to generate code:**
  1. Prefer **Utility Classes** (`ec-[name]`) for direct HTML implementation.
  2. Use **CSS Variables** (`var(--ec-[name])`) when writing custom CSS stylesheets.
  3. Toggle themes by adding `data-theme="dark"` or `data-cursor-theme="dark"` to the `<html>` tag or any parent container.

---

## 🌗 Theming

The library automatically supports two visual themes:

- **Light Theme (Default):** Icon silhouette with a thin, soft white halo.
- **Dark Theme:** Same icon with its own halo color/tuning, kept legible over dark backgrounds.

### Activation

```html
<!-- Dark theme via data-theme -->
<html data-theme="dark">

<!-- OR via data-cursor-theme -->
<html data-cursor-theme="dark">
```

```css
/* Force dark theme on a specific container */
.dark-section {
  --ec-theme: dark;
}
```

Cursors automatically swap using `[data-theme="dark"]` and `[data-cursor-theme="dark"]` selectors.

### Halo Style (Editable)

Every cursor icon is rendered with a thin, soft halo/outline behind it so it stays visible on any background. The halo is generated at build time from a single config object in `scripts/build.mjs`, so it's fully editable without touching each SVG:

```js
// scripts/build.mjs
const HALO_CONFIG = {
  radius: 1,        // outline thickness - lower = thinner
  blur: 0.6,         // outline softness - higher = softer/smoother edge
  colorLight: '#ffffff',
  colorDark: '#ffffff',
};
```

After changing any value, regenerate the CSS with:

```bash
npm run build
```

---

## 🖱️ Auto-click Cursor

Opt-in behavior that automatically swaps the browser's default `pointer`/`default` cursor for this library's **click** cursor on typical interactive elements (`a`, `button`, `[role="button"]`, form controls, `[onclick]`, focusable `[tabindex]`, etc.) - no JavaScript required.

```html
<!-- Enable everywhere -->
<html data-cursor-auto>

<!-- Or scope it to a section -->
<div data-cursor-auto>
  <a href="#">This link uses the click cursor</a>
</div>
```

To keep the browser's native cursor on a specific element even inside an auto-click area, add `data-cursor-native` to it (or to an ancestor):

```html
<div data-cursor-auto>
  <a href="#">Uses --ec-click</a>
  <a href="#" data-cursor-native>Keeps the native browser cursor</a>
</div>
```

---

## ♿ Accessibility

Essential Cursor strictly follows **WCAG 2.2** guidelines and the **CSS UI Level 4** specification:

### Met Criteria

- **1.4.11 Non-text Contrast (AA):** Minimum 3:1 contrast between cursors and backgrounds.
- **2.3.3 Target Size (AAA):** 60×60px grid with adequate touch area.
- **CSS UI Level 4:** Mandatory fallback keywords in all tokens.

### Reduced Motion

```css
@media (prefers-reduced-motion: reduce) {
  /* Static cursors, no animations */
  * {
    cursor: auto !important;
  }
}
```

### Forced Colors (High Contrast Mode)

```css
@media (forced-colors: active) {
  /* Cursors respect system colors */
  [data-cursor] {
    forced-color-adjust: auto;
  }
}
```

### Native Fallbacks

Every CSS token includes a native fallback keyword:

```css
--ec-pointer: url("data:image/svg+xml,...") 30 8, pointer;
/* If SVG fails, browser falls back to native 'pointer' */
```

---

## 📦 Bundle Size

| File | Raw Size | Gzip Size |
|---------|-----------------|----------------|
| `essential-cursors.css` | ~66 KB | ~6 KB |
| `essential-cursors.min.css` | ~65 KB | ~6 KB |

Goal achieved: **< 6 kB gzip** ✅

---

## 🧰 Contributing

### Workflow

1. **Create/Edit SVG** in `src/svg/cursor-name.svg`
   - `viewBox="0 0 60 60"`
   - Silhouette in `#111111`
   - Round linejoin/linecap
   - 2px padding on edges

2. **Update `hotspots.json`**
   ```json
   {
     "cursor-name": [x, y, "fallback-keyword"]
   }
   ```

3. **Run Build**
   ```bash
   npm run build
   ```

4. **Run Tests**
   ```bash
   npm test
   ```

5. **Validate Diff**
   ```bash
   git diff --exit-code dist
   ```

### Requirements

- Node.js >= 20
- Zero external dependencies (build uses native modules only)

---

## 🔒 Repository Security Recommendations

To maintain supply chain security:

### GitHub

1. **Branch Protection on `main`**
   - Require review before merge
   - Require green CI (`ci.yml` workflow)
   - Block force push

2. **Signed Tags**
   ```bash
   git tag -s v1.1.0 -m "Release v1.1.0"
   ```

3. **Dependabot** active for security updates

### npm

1. **Mandatory 2FA** for publishing
   ```bash
   npm profile set requires-auth always
   ```

2. **Automatic Provenance** (already enabled in `package.json`)
   - Ensures package was published from this specific repository

---

## 📄 License

**BSD-3-Clause with Additional Conditions**

See [`LICENSE`](LICENSE) file for full details.

Key terms:
- ✅ Commercial and non-commercial use allowed
- ✅ Modification and redistribution allowed
- ⚠️ **Clause 4:** Transfer to "Essential Web Tools" or affiliates is prohibited
- ⚠️ **Clause 5:** Limitation of liability extends to all contributors

---

<p align="center">
  <strong>Essential Cursor</strong> — Crafted with precision, distributed with security.
</p>

<p align="center">
  <a href="#top">Back to top ↑</a>
</p>