{"_id":"@anayap10/pika-ui","_rev":"2-8b98062b1f6f24d8c4a91b6020ec22fc","name":"@anayap10/pika-ui","dist-tags":{"latest":"0.1.2"},"versions":{"0.1.0":{"name":"@anayap10/pika-ui","version":"0.1.0","keywords":["design-system","react","components","ui","retro","arcade","wcag","accessible","a11y","a11y-aaa"],"author":{"name":"Paola Anaya"},"license":"BSD-2-Clause","_id":"@anayap10/pika-ui@0.1.0","maintainers":[{"name":"anayap10","email":"p.andrea.a93@gmail.com"}],"homepage":"https://github.com/anayap10/pika-ui#readme","bugs":{"url":"https://github.com/anayap10/pika-ui/issues"},"dist":{"shasum":"04b63d7d047f74cd60eb9a59f44cd9a8b17c76a8","tarball":"https://registry.npmjs.org/@anayap10/pika-ui/-/pika-ui-0.1.0.tgz","fileCount":7,"integrity":"sha512-YGRQga5L9BLZBtlWz6k4nwqdjvYVTntILGbL/pGNYdI0w5vMLGjOtGfNgjwgrM6z5yny8CKN+VGIiAHYFGQptQ==","signatures":[{"sig":"MEQCIGlyBgkWuMoW4z1sGmfjO1207RnxmnyTJV9bDjc9Kc65AiAEKegc3oapWg7R/lEv5zhI5wxB9M+QkDtBtqra8+sURQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":197089},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=22.12.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./package.json":"./package.json"},"gitHead":"b49d710eb073668ec76bdeec409eef1b60f9ea0e","scripts":{"dev":"vite","lint":"eslint .","test":"vitest run --project unit","build":"tsc -b && vite build","preview":"vite preview","publish":"npm publish --access public","test:all":"vitest run","build:lib":"vite build --mode lib","chromatic":"npx chromatic --project-token=chpt_9c8e3674a6fb938","storybook":"storybook dev -p 6006","test:a11y":"vitest run --project unit src/test/a11y.test.tsx","typecheck":"tsc -b","test:watch":"vitest --project unit","test:coverage":"vitest run --project unit --coverage","prepublishOnly":"npm run lint && npm run test:coverage && npm run build","test:storybook":"vitest run --project storybook","build-storybook":"storybook build"},"_npmUser":{"name":"anayap10","email":"p.andrea.a93@gmail.com"},"repository":{"url":"git+https://github.com/anayap10/pika-ui.git","type":"git"},"_npmVersion":"10.9.8","description":"A retro arcade design system — 8-bit looks, WCAG 2.2 AAA manners","directories":{},"_nodeVersion":"22.23.2","dependencies":{"react":"^19.2.0","react-dom":"^19.2.0","@fontsource/vt323":"^5.3.0","@fontsource/nunito":"^5.3.0","@fontsource/press-start-2p":"^5.3.0"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.2.4","jsdom":"^27.0.1","eslint":"^9.39.1","terser":"^5.51.2","vitest":"^4.0.16","globals":"^16.5.0","chromatic":"^16.10.1","storybook":"^10.1.10","@eslint/js":"^9.39.1","playwright":"^1.57.0","typescript":"~5.9.3","@types/node":"^24.10.1","@types/react":"^19.2.5","@sa11y/vitest":"^8.0.28","@types/react-dom":"^19.2.3","typescript-eslint":"^8.46.4","@vitest/coverage-v8":"^4.0.16","@vitejs/plugin-react":"^5.1.1","@storybook/addon-a11y":"^10.1.10","@storybook/addon-docs":"^10.1.10","@storybook/react-vite":"^10.1.10","@testing-library/react":"^16.3.3","@storybook/addon-vitest":"^10.1.10","eslint-plugin-storybook":"^10.1.10","@chromatic-com/storybook":"^4.1.3","@testing-library/jest-dom":"^6.9.1","eslint-plugin-react-hooks":"^7.0.1","@vitest/browser-playwright":"^4.0.16","@testing-library/user-event":"^14.6.7","eslint-plugin-react-refresh":"^0.4.24"},"_npmOperationalInternal":{"tmp":"tmp/pika-ui_0.1.0_1788893308494_0.9510687904052639","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"_id":"@anayap10/pika-ui@0.1.2","bugs":{"url":"https://github.com/anayap10/pika-ui/issues"},"dist":{"shasum":"486fe8f3e4bbdcb33547498e784fe76b009b6a97","tarball":"https://registry.npmjs.org/@anayap10/pika-ui/-/pika-ui-0.1.2.tgz","fileCount":7,"integrity":"sha512-GbcAayKMr+U0LnbIOEA3nNCkJYLOTXTObFfBwH/rJV4nw0tJhF12o0dacqTiiid+Bbg7qMCjEiiiHlmX1HchYQ==","signatures":[{"sig":"MEQCID8VcyxXw+YfrhPQwfwk0tHN5JqFVf34UlukvnJlBtJXAiBF/0SKTZUsqwkDvksy7v6W2pu/3DdFg+AVXxedqMdURQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCICTLi1miatvKThWN9ve/sFqJNdhQT0RvQvjmxs6wuyJsAiAS2O3nVCFNjnBHwitm4fZ45JoPHcCaAxU+Cw4ddB6g7g=="}],"unpackedSize":212486},"main":"./dist/index.cjs","name":"@anayap10/pika-ui","type":"module","types":"./dist/index.d.ts","author":{"name":"Paola Anaya"},"module":"./dist/index.js","engines":{"node":">=22.12.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./package.json":"./package.json"},"gitHead":"41767e1397272ef01543a039d6a0f5d19d5b7ab2","license":"BSD-2-Clause","scripts":{"dev":"vite","lint":"eslint .","test":"vitest run --project unit","build":"tsc -b && vite build","preview":"vite preview","publish":"npm publish --access public","test:all":"vitest run","build:lib":"vite build --mode lib","chromatic":"npx chromatic --project-token=chpt_9c8e3674a6fb938","storybook":"storybook dev -p 6006","test:a11y":"vitest run --project unit src/test/a11y.test.tsx","typecheck":"tsc -b","test:watch":"vitest --project unit","test:coverage":"vitest run --project unit --coverage","prepublishOnly":"npm run lint && npm run test:coverage && npm run build","test:storybook":"vitest run --project storybook","build-storybook":"storybook build"},"version":"0.1.2","_npmUser":{"name":"anayap10","email":"p.andrea.a93@gmail.com"},"homepage":"https://github.com/anayap10/pika-ui#readme","keywords":["design-system","react","components","ui","retro","arcade","wcag","accessible","a11y","a11y-aaa"],"repository":{"url":"git+https://github.com/anayap10/pika-ui.git","type":"git"},"_npmVersion":"10.9.0","description":"A retro arcade design system — 8-bit looks, WCAG 2.2 AAA manners","directories":{},"maintainers":[{"name":"anayap10","email":"p.andrea.a93@gmail.com"}],"_nodeVersion":"22.12.0","dependencies":{"react":"^19.2.0","react-dom":"^19.2.0","@fontsource/vt323":"^5.3.0","@fontsource/nunito":"^5.3.0","@fontsource/press-start-2p":"^5.3.0"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.2.4","jsdom":"26.1.0","eslint":"^9.39.1","terser":"^5.51.2","vitest":"^4.0.16","globals":"^16.5.0","chromatic":"^16.10.1","storybook":"^10.1.10","@eslint/js":"^9.39.1","playwright":"^1.57.0","typescript":"~5.9.3","@types/node":"^24.10.1","@types/react":"^19.2.5","@sa11y/vitest":"^8.0.28","@types/react-dom":"^19.2.3","typescript-eslint":"^8.46.4","@vitest/coverage-v8":"^4.0.16","@vitejs/plugin-react":"^5.1.1","@storybook/addon-a11y":"^10.1.10","@storybook/addon-docs":"^10.1.10","@storybook/react-vite":"^10.1.10","@testing-library/react":"^16.3.3","@storybook/addon-vitest":"^10.1.10","eslint-plugin-storybook":"^10.1.10","@chromatic-com/storybook":"^4.1.3","@testing-library/jest-dom":"^6.9.1","eslint-plugin-react-hooks":"^7.0.1","@vitest/browser-playwright":"^4.0.16","@testing-library/user-event":"^14.6.7","eslint-plugin-react-refresh":"^0.4.24"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/pika-ui_0.1.2_1789423482451_0.7277947568740488"}}},"time":{"created":"2026-09-08T18:48:28.286Z","modified":"2026-09-14T22:04:42.734Z","0.1.0":"2026-09-08T18:48:28.631Z","0.1.2":"2026-09-14T22:04:42.565Z"},"bugs":{"url":"https://github.com/anayap10/pika-ui/issues"},"author":{"name":"Paola Anaya"},"license":"BSD-2-Clause","homepage":"https://github.com/anayap10/pika-ui#readme","keywords":["design-system","react","components","ui","retro","arcade","wcag","accessible","a11y","a11y-aaa"],"repository":{"url":"git+https://github.com/anayap10/pika-ui.git","type":"git"},"description":"A retro arcade design system — 8-bit looks, WCAG 2.2 AAA manners","maintainers":[{"name":"anayap10","email":"p.andrea.a93@gmail.com"}],"readme":"# Pika UI\n\n**A retro arcade design system — 8-bit looks, WCAG 2.2 AAA manners.**\n\n[![CI](https://github.com/anayap04/pika-ui/actions/workflows/ci.yml/badge.svg)](https://github.com/anayap04/pika-ui/actions/workflows/ci.yml)\n![Coverage](https://img.shields.io/badge/coverage-%E2%89%A585%25-brightgreen)\n[![SonarCloud Quality Gate](https://sonarcloud.io/api/project_badges/measure?project=anayap04_pika-ui&metric=alert_status)](https://sonarcloud.io/project/overview?id=anayap04_pika-ui)\n\nPika UI is the React component library behind the *Gender Reveal Voting App*. It\ntakes the warmth of an old arcade cabinet — hard 4px borders, a pink-and-gold\npalette, `Press Start 2P` / `VT323` lettering, zero border-radius — and holds\nevery one of those choices to the **AAA level of WCAG 2.2**: 7:1 text contrast,\n3px focus rings, 44px tap targets and full reduced-motion support.\n\n---\n\n## Project health\n\n| Area | Status | Notes |\n| --- | --- | --- |\n| **Build** | ✅ passing | `npm run build` (tsc project refs + Vite 7) and `npm run build-storybook` both clean |\n| **Types** | ✅ passing | `tsc -b`, strict, no errors |\n| **Lint** | ✅ passing | flat ESLint config (`@eslint/js`, `typescript-eslint`, React Hooks, Storybook) — 0 warnings |\n| **Tests** | ✅ passing | **unit tests** (Vitest 4 + jsdom + Testing Library) for every atom, molecule and token module, **`@sa11y/vitest` `toBeAccessible` axe checks** on every component, plus story smoke / a11y tests via `@storybook/addon-vitest` in a real browser (Playwright Chromium) |\n| **Accessibility** | 🎯 AAA, both themes | **CI-blocking** `@sa11y/vitest` axe checks (WCAG 2.1 A/AA base ruleset) on every component in the unit suite — roles, names, label associations, ARIA. Plus `@storybook/addon-a11y` per-story with the full WCAG 2.2 rule set **and** axe `color-contrast-enhanced` (AAA 7:1); every text pairing verified ≥7:1 in light **and** dark (jsdom has no layout, so contrast is checked in the browser project, not the sa11y unit tests) |\n| **Theming** | ✅ light + dark | `src/tokens/colors.css` drives `--pk-*` custom properties; components read them via `theme` in `src/tokens`. Switches on `[data-theme]`, `.dark`, or `prefers-color-scheme`. Storybook has a **Theme** toolbar toggle |\n| **Visual regression** | ✅ wired | Chromatic project configured (`npm run chromatic`) |\n| **Coverage** | ✅ 100% · 85% gate | `@vitest/coverage-v8` over `src/components`, `src/tokens`, `src/utils`; **CI fails below 85%** (statements / branches / functions / lines). Run `npm run test:coverage` |\n| **CI** | ✅ GitHub Actions | `.github/workflows/ci.yml` runs lint → types → unit tests + coverage → build, plus a Storybook browser-test job, on every push to `main` and PR |\n| **SonarCloud** | ⚠️ Gate not computed | [Project health dashboard](https://sonarcloud.io/project/overview?id=anayap04_pika-ui): 19 open issues, 7.4% duplication, security rating C, security review A, reliability A, maintainability A |\n| **Release** | ✅ v0.1.1 | Published to NPM as `@anayap10/pika-ui`; see [releases](https://github.com/anayap04/pika-ui/releases) |\n| **Docs** | ✅ living | Storybook is the source of truth — `Overview/Introduction` homepage + autodocs on every component |\n\n### Component inventory\n\n| Layer | Count | Components |\n| --- | --- | --- |\n| **Atoms** | 8 | Button · Card · Input · Typography (Heading / Paragraph / Text) · Badge · Checkbox · Radio · Toggle · Tags |\n| **Molecules** | 5 | FormField · RadioGroup · CheckboxGroup · ButtonGroup · CardSection |\n| **Organisms** | 0 | planned (Phase 4) |\n\n### Known gaps / tech debt\n\n- **Phase 4 (Organisms)** — Complex composite components planned for future releases.\n\n---\n\n## Getting started\n\n**Requirements:** Node.js `22.12+` (Storybook 10).\n\n### From NPM (as a consumer)\n\n```bash\nnpm install @anayap10/pika-ui\n```\n\n### Local development (contributing to Pika UI)\n\n```bash\ngit clone https://github.com/anayap04/pika-ui.git\ncd pika-ui\nnpm install\nnpm run storybook      # dev — http://localhost:6006\n```\n\n| Script | What it does |\n| --- | --- |\n| `npm run storybook` | Storybook dev server (component workbench + docs) |\n| `npm run build-storybook` | static Storybook build → `storybook-static/` |\n| `npm run build` | type-check + library build (ESM + CommonJS) → `dist/` |\n| `npm run lint` | ESLint over the repo |\n| `npm run typecheck` | `tsc -b` project-reference type-check |\n| `npm test` | run the unit test suite (Vitest `unit` project, jsdom) |\n| `npm run test:watch` | unit tests in watch mode |\n| `npm run test:coverage` | unit tests + v8 coverage report (fails under 85%) |\n| `npm run test:a11y` | just the `@sa11y/vitest` accessibility matrix ([src/test/a11y.test.tsx](src/test/a11y.test.tsx)) |\n| `npm run test:storybook` | story smoke + a11y suite in a real browser (needs Playwright) |\n| `npm run test:all` | both Vitest projects (`unit` + `storybook`) |\n| `npm run chromatic` | push a visual-regression build to Chromatic |\n| `npm publish` | publish to NPM (CI automation via GitHub Actions on version tags) |\n\n---\n\n## Testing\n\nTwo Vitest **projects** run from one config ([vite.config.ts](vite.config.ts)):\n\n| Project | Environment | Scope | Command |\n| --- | --- | --- | --- |\n| `unit` | jsdom + `@testing-library/react` | `src/**/*.test.{ts,tsx}` — behaviour, props, variants, a11y wiring | `npm test` |\n| `storybook` | Playwright Chromium | every `*.stories.tsx` — render smoke + `@storybook/addon-a11y` | `npm run test:storybook` |\n\n### Accessibility (`@sa11y/vitest`)\n\n[src/test/setup.ts](src/test/setup.ts) calls `setup()` from\n[`@sa11y/vitest`](https://www.npmjs.com/package/@sa11y/vitest), which registers the\nasync `toBeAccessible` matcher (axe-core, WCAG 2.1 A/AA base ruleset).\n[src/test/a11y.test.tsx](src/test/a11y.test.tsx) renders every atom and molecule in\nrepresentative configurations and asserts:\n\n```tsx\nrender(<Toggle label=\"Dark mode\" />);\nawait expect(document.body).toBeAccessible();\n```\n\nThese run inside the `unit` project, so **CI fails on a structural a11y regression**\n(missing label, bad role, broken ARIA). jsdom has no layout engine, so\ncolour-contrast rules do not run here — AAA contrast stays covered by\n`@storybook/addon-a11y` (`color-contrast-enhanced`) in the browser project.\nThe matcher's type is declared in [src/test/sa11y.d.ts](src/test/sa11y.d.ts).\n\n### Coverage\n\nMeasured over the `unit` project only (`src/components`, `src/tokens`,\n`src/utils`), reported as `text` / `html` / `lcov` into `coverage/`, and gated at\n**85%** for statements, branches, functions and lines. Barrel `index.ts` files and\nthe deprecated `components/{Button,Card,Input}.tsx` shims are excluded.\n\n```bash\nnpm run test:coverage        # -> coverage/index.html\n```\n\nCI runs the same gate — see [`.github/workflows/ci.yml`](.github/workflows/ci.yml).\n\n---\n\n## Design foundations\n\n| Token group | Source of truth | Highlights |\n| --- | --- | --- |\n| **Colour** | `src/tokens/index.ts` + `src/tokens/colors.css` | light + dark `--pk-*` custom properties; decorative tints for fills only; every text pairing uses a `*Strong` / `*Text` token verified ≥7:1 (AAA) in both themes |\n| **Effects** | `shadows` token + `src/tokens/effects.css` | pixel depth is stacked hard offsets of `--pk-border` (`--pk-shadow-pixel` / `-elevated`) — never a blur; `.crt-effect` scanline overlay is opt-in and off under `prefers-reduced-motion` |\n| **Type** | `src/styles/fonts.ts` (self-hosted `@fontsource`) | `Press Start 2P` (display / H1), `VT323` (UI / labels — single 400 weight), `Nunito` (body) |\n| **Spacing** | `spacing` token | 4 · 8 · 16 · 24 · 32 px hard grid |\n| **Radius** | `radii` token | `0px` everywhere — pixel art has no rounded corners |\n| **Motion** | `transitions` token | 150–300 ms; all looping effects disabled under `prefers-reduced-motion` |\n\n### Accessibility commitments (WCAG 2.2)\n\n- **SC 1.4.6 Contrast (AAA)** — body text ≥ 7:1, large text ≥ 4.5:1; checked in the\n  a11y panel via `color-contrast-enhanced`.\n- **SC 2.4.7 / 2.4.11 Focus Visible / Not Obscured** — 3px solid ring, 2px offset.\n- **SC 2.5.8 Target Size** — interactive controls ≥ 44×44px (spec minimum is 24px).\n- **SC 2.2.2 Pause, Stop, Hide** — `prefers-reduced-motion` disables pixel-float,\n  pulse, blink and the CRT scanline overlay.\n- **SC 1.4.11 Non-text Contrast** — borders, switch tracks and focus rings ≥ 3:1.\n\n---\n\n## Project structure\n\n```\n.github/\n  workflows/\n    ci.yml          Lint, type-check, unit tests, coverage gate, build on every push/PR\n    publish.yml     Test → Build → Publish to NPM on version tags\n.storybook/         Storybook config — retro AAA manager theme, a11y, light/dark toggle\nsrc/\n  components/\n    atoms/          Button, Card, Input, Typography, Badge, Checkbox, Radio, Toggle, Tags\n    molecules/      FormField, RadioGroup, CheckboxGroup, ButtonGroup, CardSection\n    organisms/      (planned — Phase 4)\n  stories/\n    Overview.mdx    design-system homepage\n  styles/\n    fonts.ts        self-hosted @fontsource webfonts\n  tokens/\n    index.css       the one stylesheet to link — @imports the partials below\n    colors.css      --pk-* colour tokens (light + dark, OS-follow + opt-in)\n    typography.css spacing.css motion.css effects.css   value tokens\n    base.css        global baseline + the a11y rules that need real CSS\n    fonts.css       Google-Fonts CDN fallback (not imported by index.css)\n    index.ts        the JS mirror of the tokens + the `theme` var accessor\n  test/\n    setup.ts        jest-dom + `@sa11y/vitest` matchers, Testing Library cleanup (`unit` project)\n    a11y.test.tsx   `toBeAccessible` axe checks for every component\n    sa11y.d.ts      `toBeAccessible` matcher type augmentation\n.nvmrc              Node version lock (22.12.0)\ndesign-tokens.json  stale v3 export — superseded by src/tokens/\n```\n\nEach component folder is `Component.tsx` + `Component.stories.tsx` +\n`Component.test.tsx` + `index.ts`.\n\n---\n\n## License\n\nBSD 2-Clause © 2026 Paola Anaya\n","readmeFilename":"README.md"}