npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mostajs/palette

v0.2.0

Published

Composition de palettes accessibles (zéro dépendance) : contraste WCAG, dérivation de tokens sémantiques garantis lisibles, audit et sortie CSS. Peu d'entrées, beaucoup de dérivation, une porte de validation — un sélecteur de couleur ne sait pas dire non,

Readme

@mostajs/palette

Auteur : Dr Hamid MADANI [email protected] Licence : AGPL-3.0-or-later · Zéro dépendance · ESM

Composition de palettes accessibles. On n'y saisit pas dix-neuf couleurs : on en donne trois de marque et quatre d'état, et tout le reste — surfaces, textes, filets, survols, anneau de focus, fonds d'alerte — est dérivé, puis validé contre les seuils WCAG.

Un sélecteur de couleur ne sait pas dire non. Ce module le sait. C'est toute sa raison d'être : les bordures invisibles (1,5:1), les ors illisibles (2,1:1) et les gris hors seuil ne naissent pas d'une négligence — ils naissent d'un outil qui accepte tout. Ici, derive() corrige une couleur qui n'atteint pas son seuil au lieu de l'émettre telle quelle.

Le principe : nommer par la fonction, pas par la couleur

Tant qu'un token s'appelle --gold, quelqu'un finira par l'utiliser comme couleur de texte — et il sera à 2:1 sur blanc. S'il s'appelle --text, --line, --field-border ou --focus-ring, la question ne se pose plus : la valeur est dérivée et garantie.

Usage

import { compose } from '@mostajs/palette';

const { tokens, report, css } = compose({ brand: '#06284A', accent: '#C9952C' });

report.pass;   // true — aucun couple sous son seuil
css;           // ':root{--text:#0F172A;--line:…;--focus-ring:#bc8b29;--radius-md:8px;…}'

API

| Fonction | Rôle | |---|---| | contrast(a, b) | rapport WCAG (1 → 21) | | check(fg, bg, { size }) | verdict : { ratio, aa, aaa, level }size = normal (4,5) · large (3) · ui (3, bordures et icônes) | | mix / lighten / darken / scale | manipulation et rampe 50→900 | | readableOn(bg) | la couleur de texte lisible sur ce fond | | ensureContrast(c, bg, { min }) | la porte : corrige c jusqu'au seuil (fond clair → fonce ; fond sombre → éclaircit) | | derive(input) | le cœur : entrées → tokens sémantiques garantis lisibles | | audit(tokens) | la table de contrastes (les 16 couples exigés par CONTRACTS) | | toCss(tokens) | bloc :root{…} — couleurs + échelles (rayon, espace, ombre, mouvement, typographie) | | compose(input, { strict }) | façade : { input, tokens, report, css } |

Filet décoratif ≠ contour porteur

Deux tokens, et la distinction est normative :

  • --line — séparateur, contour de carte : décoratif, aucun seuil imposé, il reste léger (comme un #CBD5E1).
  • --field-border — contour de champ, limite cliquable : il porte une information, donc ≥ 3:1 (WCAG 1.4.11).

Les confondre, c'est soit alourdir tout le design, soit rendre les formulaires invisibles.

Garanties (testées)

  • Vecteurs de référence WCAG : noir/blanc = 21:1 · #767676 sur blanc = 4,54:1 (la limite AA officielle) · #949494 = 3,0:1 → échec.
  • Invariant central : pour 24 combinaisons de marque/accent volontairement hostiles (jaunes pâles, gris clairs), audit(derive(...)) passe toujours. Aucune palette illisible n'est productible.
  • L'anneau de focus est un token de première classe : toujours ≥ 3:1, même à partir d'un accent pâle.
  • Le texte des alertes est validé sur le fond d'alerte, pas sur le blanc.

28 tests verts (@mostajs/mjs-unit) : npm test.

Échelles fournies

Grille de 8 px (8/16/24/32/48/64) · rayons 4/8/12/16/24 · trois ombres · deux durées + une courbe · typographie 32/24/20/16/14/12/11 avec graisses et interlignes.