{"_id":"@didrod2539/okcolor","_rev":"2-7e736e6cac84fdc1a857ff58a81b4ce3","name":"@didrod2539/okcolor","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"@didrod2539/okcolor","version":"0.1.0","keywords":["color","colour","oklch","oklab","hsl","hex","wcag","contrast","accessibility","a11y","color-conversion","palette","zero-dependency"],"author":{"url":"https://github.com/didrod205","name":"didrod205"},"license":"MIT","_id":"@didrod2539/okcolor@0.1.0","maintainers":[{"name":"didrod2539","email":"ykc205@naver.com"}],"homepage":"https://github.com/didrod205/okcolor#readme","bugs":{"url":"https://github.com/didrod205/okcolor/issues"},"dist":{"shasum":"fa542e82f4e5b1bda1c0eec6c50afb44eddf8b6c","tarball":"https://registry.npmjs.org/@didrod2539/okcolor/-/okcolor-0.1.0.tgz","fileCount":9,"integrity":"sha512-faprMJHFNaox5tjHMK3rrdIW5X0wVkRUcdjIwUKCNnLhoxpiKDLON8S7UUhnnUuvPDEhozZjR13vCOkgcP09TA==","signatures":[{"sig":"MEQCIE0HT2I3kPxPL3e/SzcIubPOZdP051+nr7dGbWML327TAiAdYpa/QrGcd3OaySC6TtaCDabT4IkD6xHXKRwdlMRdQA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":111789},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"2ee840d22ee7e46572014ebe923f03d5e78969c5","scripts":{"lint":"tsc --noEmit","test":"vitest run","build":"tsup","coverage":"vitest run --coverage","typecheck":"tsc --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"didrod2539","email":"ykc205@naver.com"},"repository":{"url":"git+https://github.com/didrod205/okcolor.git","type":"git"},"_npmVersion":"11.12.1","description":"Tiny, zero-dependency color toolkit with modern OKLab/OKLCH color science and WCAG accessibility. Parse, convert, mix perceptually, and check contrast. Works in Node, Deno, Bun and the browser.","directories":{},"sideEffects":false,"_nodeVersion":"25.9.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","vitest":"^2.1.8","typescript":"^5.7.2","@vitest/coverage-v8":"^2.1.8"},"_npmOperationalInternal":{"tmp":"tmp/okcolor_0.1.0_1780062110096_0.613347979201029","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@didrod2539/okcolor","version":"0.2.0","publishConfig":{"access":"public"},"description":"Tiny, zero-dependency color toolkit with modern OKLab/OKLCH color science and WCAG accessibility. Parse, convert, mix perceptually, and check contrast. Works in Node, Deno, Bun and the browser.","type":"module","main":"./dist/index.js","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"sideEffects":false,"engines":{"node":">=18"},"scripts":{"build":"tsup","test":"vitest run","test:watch":"vitest","coverage":"vitest run --coverage","typecheck":"tsc --noEmit","lint":"tsc --noEmit","prepublishOnly":"npm run build"},"keywords":["color","colour","oklch","oklab","hsl","hex","wcag","contrast","accessibility","a11y","color-conversion","palette","zero-dependency","cli"],"author":{"name":"didrod205","url":"https://github.com/didrod205"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/didrod205/okcolor.git"},"bugs":{"url":"https://github.com/didrod205/okcolor/issues"},"homepage":"https://github.com/didrod205/okcolor#readme","devDependencies":{"@types/node":"^22.19.19","@vitest/coverage-v8":"^2.1.8","tsup":"^8.3.5","typescript":"^5.7.2","vitest":"^2.1.8"},"bin":{"okcolor":"dist/cli.js"},"gitHead":"9c638c30d9a1a9be2de1e8fc13a2a9340655b112","_id":"@didrod2539/okcolor@0.2.0","_nodeVersion":"25.9.0","_npmVersion":"11.12.1","dist":{"integrity":"sha512-gTT3j6zAuR2JQbCzo5/KEyK7QdltYOcXrChaqi6dJWsjYGlxfZL3jKAnE+DoViK5zFs7PwhC+hd/CHWbRbsxOw==","shasum":"7da402b199261349d328da5d01a11ba16b94d5a6","tarball":"https://registry.npmjs.org/@didrod2539/okcolor/-/okcolor-0.2.0.tgz","fileCount":15,"unpackedSize":189208,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQD69Y31ZYbg2+tdi4LujSnv5S9hVsoua1QwBnpe0WHVCQIgMn6yxEsq4kt27NaR0N56wMJRiYB69HNWoKXcEB31JOI="}]},"_npmUser":{"name":"didrod2539","email":"ykc205@naver.com"},"directories":{},"maintainers":[{"name":"didrod2539","email":"ykc205@naver.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/okcolor_0.2.0_1780374840718_0.1066703399825848"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-29T13:41:49.870Z","modified":"2026-06-02T04:34:00.990Z","0.1.0":"2026-05-29T13:41:50.297Z","0.2.0":"2026-06-02T04:34:00.872Z"},"bugs":{"url":"https://github.com/didrod205/okcolor/issues"},"author":{"name":"didrod205","url":"https://github.com/didrod205"},"license":"MIT","homepage":"https://github.com/didrod205/okcolor#readme","keywords":["color","colour","oklch","oklab","hsl","hex","wcag","contrast","accessibility","a11y","color-conversion","palette","zero-dependency","cli"],"repository":{"type":"git","url":"git+https://github.com/didrod205/okcolor.git"},"description":"Tiny, zero-dependency color toolkit with modern OKLab/OKLCH color science and WCAG accessibility. Parse, convert, mix perceptually, and check contrast. Works in Node, Deno, Bun and the browser.","maintainers":[{"name":"didrod2539","email":"ykc205@naver.com"}],"readme":"<div align=\"center\">\n\n# okcolor\n\n**Modern color for the web — OKLab/OKLCH color science and WCAG accessibility in one tiny, zero-dependency package.**\n\n[![npm version](https://img.shields.io/npm/v/@didrod2539/okcolor.svg?color=success)](https://www.npmjs.com/package/@didrod2539/okcolor)\n[![bundle size](https://img.shields.io/bundlephobia/minzip/@didrod2539/okcolor?label=gzip)](https://bundlephobia.com/package/@didrod2539/okcolor)\n[![CI](https://github.com/didrod205/okcolor/actions/workflows/ci.yml/badge.svg)](https://github.com/didrod205/okcolor/actions/workflows/ci.yml)\n[![types](https://img.shields.io/npm/types/@didrod2539/okcolor.svg)](https://www.npmjs.com/package/@didrod2539/okcolor)\n[![license](https://img.shields.io/npm/l/@didrod2539/okcolor.svg)](./LICENSE)\n\n</div>\n\nColor math is unforgiving: a \"lighter\" shade in naive HSL looks muddy, and a\nWCAG contrast ratio is a precise formula (sRGB linearization → relative\nluminance), not a vibe. **okcolor** does both correctly — it lightens and mixes\nin **OKLab** (perceptually uniform) and computes **WCAG** contrast exactly —\nin about 3 KB with zero dependencies.\n\n```ts\nimport { color, contrast, readableTextColor } from \"@didrod2539/okcolor\";\n\ncolor(\"#3498db\").lighten(0.1).toHex();        // perceptual lightening, not HSL\ncolor(\"red\").mix(\"blue\").toHex();             // \"#8c53a2\" — clean OKLab midpoint\ncontrast(\"#777\", \"#fff\");                     // 4.48  (exact WCAG ratio)\ncolor(\"#767676\").isReadable(\"#fff\");          // true  (meets AA)\nreadableTextColor(\"#3498db\").toHex();         // \"#000000\" — auto pick black/white\n```\n\n---\n\n## Why okcolor?\n\n- 🎨 **OKLab/OKLCH built in.** `lighten`, `darken`, `mix`, `grayscale` all operate in OKLab, so results look right — no muddy purples, no uneven lightness ramps.\n- ♿ **WCAG accessibility, exact.** Relative luminance, contrast ratio, and `isReadable` (AA/AAA, normal/large) — the math accessibility audits actually use.\n- 🔁 **Every format.** Parse and emit hex (3/4/6/8), `rgb()`, `hsl()`, `oklch()`, and all 148 CSS named colors.\n- 🧊 **Immutable & chainable.** `color(\"#abc\").darken(0.1).saturate(0.2).alpha(0.8).toHslString()`.\n- 🪶 **~3 KB gzipped, zero dependencies.** Node 18+, Deno, Bun, Workers and the browser.\n- 🛡️ **Type-safe.** Written in TypeScript, ships full declarations.\n\n## Install\n\n```bash\nnpm install @didrod2539/okcolor\n# or: pnpm add @didrod2539/okcolor  /  yarn add @didrod2539/okcolor\n```\n\n> Published under the `@didrod2539` npm scope (the unscoped name `okcolor` was\n> blocked by npm for being too close to `color`). The import name matches the\n> package name; everything else is identical.\n\nShips ESM **and** CommonJS:\n\n```ts\nimport { color } from \"@didrod2539/okcolor\";        // ESM / TypeScript\nconst { color } = require(\"@didrod2539/okcolor\");   // CommonJS\n```\n\n## CLI\n\n```bash\nnpx @didrod2539/okcolor \"#3b82f6\"              # all formats + a swatch\nnpx @didrod2539/okcolor convert rebeccapurple --to oklch\nnpx @didrod2539/okcolor contrast \"#fff\" \"#777\" # ratio + WCAG (exit 1 if AA fails)\nnpx @didrod2539/okcolor mix red blue           # perceptual OKLab midpoint\nnpx @didrod2539/okcolor shades \"#3b82f6\"       # a lighten→darken ramp\n```\n\nThe bundled command is **`okcolor`**. `contrast` exits non-zero when a pair\nfails WCAG AA — drop it into CI to guard your color tokens.\n\n## Usage\n\n### Parse & convert\n\n```ts\ncolor(\"#3498db\").toRgbString();   // \"rgb(52, 152, 219)\"\ncolor(\"rgb(52 152 219)\").toHsl(); // { h: 204, s: 70, l: 53, a: 1 }\ncolor(\"rebeccapurple\").toOklchString(); // \"oklch(0.4422 0.1656 303.37)\"\ncolor(\"hsl(210 50% 50%)\").toHex();      // \"#4080bf\"\ncolor(\"oklch(0.7 0.15 250)\").toHex();   // OKLCH in, hex out\n```\n\n### Manipulate (perceptually)\n\n```ts\nconst brand = color(\"#3498db\");\n\nbrand.lighten(0.1);     // +0.1 OKLCH lightness\nbrand.darken(0.1);\nbrand.saturate(0.2);    // +20% chroma\nbrand.desaturate(0.2);\nbrand.rotate(180);      // complementary hue\nbrand.grayscale();      // chroma → 0, lightness preserved\nbrand.mix(\"white\", 0.25);          // 25% toward white, in OKLab\nbrand.mix(\"white\", 0.25, \"srgb\");  // ...or naive sRGB if you prefer\nbrand.alpha(0.5).toRgbString();    // \"rgba(52, 152, 219, 0.5)\"\n```\n\n### Accessibility (WCAG 2.1)\n\n```ts\ncolor(\"#fff\").luminance();              // 1\ncontrast(\"#000\", \"#fff\");               // 21\n\nconst fg = color(\"#767676\");\nfg.isReadable(\"#ffffff\");                       // true  (AA, normal text)\nfg.isReadable(\"#ffffff\", { level: \"AAA\" });     // false\nfg.isReadable(\"#ffffff\", { size: \"large\" });    // true\n\n// Auto-pick legible text for any background\nreadableTextColor(\"#3498db\").toHex();   // \"#000000\"\nreadableTextColor(\"#1a1a1a\").toHex();   // \"#ffffff\"\n```\n\n## API\n\n| Member | Description |\n| ------ | ----------- |\n| `color(input)` | Parse a hex/rgb/hsl/oklch/named string, `{r,g,b,a}`, or `Color`. |\n| `oklch(l, c, h, a?)` | Build a color from OKLCH coordinates. |\n| `.toHex()` / `.toHexa()` / `.toRgbString()` / `.toHslString()` / `.toOklchString()` | Output formats. |\n| `.rgba` / `.toHsl()` / `.toOklch()` | Structured values. |\n| `.lighten` / `.darken` / `.saturate` / `.desaturate` / `.rotate` / `.grayscale` / `.invert` / `.alpha` | Manipulation (return new `Color`). |\n| `.mix(other, weight?, mode?)` | Blend in `\"oklab\"` (default) or `\"srgb\"`. |\n| `.luminance()` / `.contrast(other)` / `.isReadable(bg, opts?)` / `.isLight()` / `.isDark()` | WCAG accessibility. |\n| `contrast(a, b)` | Contrast ratio of two colors. |\n| `readableTextColor(bg)` | Black or white — whichever is more legible. |\n| `isValid(str)` | Does the string parse? |\n\n## Why OKLab?\n\nHSL's \"lightness\" doesn't match human perception: yellow at `50%` looks far\nbrighter than blue at `50%`. **OKLab** (Björn Ottosson, 2020) is a\nperceptually-uniform space, so equal lightness steps *look* equal and color\nmixes pass through sensible midpoints instead of grey mud. okcolor implements\nthe full sRGB → linear → LMS → OKLab pipeline, so `lighten`, `mix` and\n`grayscale` behave the way a designer expects.\n\n## Comparison\n\n|                          | `okcolor` | naive hex/HSL helpers | larger color libs |\n| ------------------------ | :-------: | :-------------------: | :---------------: |\n| OKLab / OKLCH            |    ✅     |          ❌           |        ⚠️         |\n| WCAG contrast & a11y     |    ✅     |          ❌           |        ⚠️         |\n| Perceptual mix/lighten   |    ✅     |          ❌           |        ⚠️         |\n| Zero dependencies        |    ✅     |          ✅           |        ⚠️         |\n| ~3 KB gzipped            |    ✅     |          ✅           |        ❌         |\n\n## Contributing\n\nContributions are very welcome! Please read [CONTRIBUTING.md](./CONTRIBUTING.md)\nand our [Code of Conduct](./CODE_OF_CONDUCT.md).\n\n```bash\ngit clone https://github.com/didrod205/okcolor.git\ncd okcolor\nnpm install\nnpm test\n```\n\n## 💖 Sponsor\n\n`okcolor` is free and MIT-licensed, built and maintained in spare time. If it\nmade your palettes prettier or your UI more accessible, please consider\nsupporting it — every bit helps keep the project healthy.\n\n- ⭐ **Star this repo** — the simplest, free way to help others discover it.\n- 🍋 **[Sponsor via Lemon Squeezy](https://elab-studio.lemonsqueezy.com/checkout/buy/5d059b89-51d0-456b-b33a-ed56994f7010)** — one-time or recurring support.\n\n> Sponsoring? Open an issue and we'll add your name/logo here. Thank you! 🙏\n\n## License\n\n[MIT](./LICENSE) © okcolor contributors\n","readmeFilename":"README.md"}