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

zink-css

v0.1.1

Published

Paper, tape and marker. A small, framework-free CSS kit for handmade-looking websites.

Readme

zink-css

Paper, tape, marker. A small CSS kit for websites that look handmade.

No JavaScript, framework or runtime dependency. One stylesheet, scoped under .zk. Textures use CSS gradients. Your existing reset stays yours.

Start

npm i zink-css

With a CSS-aware bundler (Vite, webpack, Parcel):

import 'zink-css';
// Explicit file export also works:
// import 'zink-css/zink.css';

Plain HTML, using your locally copied stylesheet:

<link rel="stylesheet" href="./zink.css">
<section class="zk zk-paper">
  <article class="zk-card zk-card--rough zk-taped">
    <h2 class="zk-heading">Hello, ink.</h2>
    <p>Your words go here.</p>
    <a class="zk-button" href="/about">Meet the maker ↗</a>
  </article>
</section>

Keep every component inside a .zk ancestor. The wrapper can be body or a small section in an existing app. Add .zk-paper to that same wrapper for the textured page background. Card backgrounds use the paper token, not a raster image. No global selector changes elements outside .zk.

Pieces

| Piece | Classes | Notes | | --- | --- | --- | | Layout | zk-wrap, zk-grid, zk-row, zk-stack, zk-section, zk-flow | Fluid wrapper, auto-fit columns, wrapping rows, rhythm, sections, text measure | | Paper | zk-paper, zk-graph, zk-lined, zk-ink | Grain, graph, ruled paper, dark ink | | Type | zk-title, zk-heading, zk-label, zk-muted, zk-scribble | Display, headings, labels, secondary text, margin notes | | Marks | zk-mark, zk-mark--pink, zk-mark--mint, zk-underline | Markers wrap across lines; default highlight is yellow | | Cards | zk-card, zk-card--rough, zk-clipping | Ink border, hard shadow, organic border radius, cut-paper clipping | | Tape | zk-taped, zk-taped--pink | Decorative pseudo-element; combine with positioned card | | Notes | zk-note, zk-note--pink, zk-note--mint | Sticky-note colour variants | | Angles | zk-tilt-left, zk-tilt-right | Small rotation, removed on narrow screens and in print | | Buttons | zk-button, zk-button--pink, zk-button--plain, zk-button--ink | Use a real button or link, not a div | | Small bits | zk-badge, zk-badge--pink, zk-stamp, zk-kbd, zk-rule | Badges, dashed stamp, keycaps, dashed divider | | Navigation | zk-nav, zk-brand | Wraps when space runs out; does not add a JS menu | | Quotes | zk-quote | Use blockquote with p and cite | | Feedback | zk-alert, zk-alert--warning, zk-alert--error | Native content blocks; use ARIA only when appropriate | | Forms | zk-field, zk-input, zk-help, zk-check | Labels, native fields, hints, checkbox rows | | Disclosure | zk-details | Use native details and summary | | Tables | zk-table-wrap, zk-table | Horizontally scrolling wrapper when needed | | Code | zk-code | Use pre/code; no syntax highlighter | | Assistive | zk-sr-only | Visually hidden accessible text |

zk-taped uses ::before. Avoid combining it with another component that needs the same pseudo-element. Prefer an outer wrapper. Rotations can overlap neighbours, so leave space around tilted cards. Tape is decorative and must not carry essential content.

Examples

Marker heading

<h1 class="zk-title">Less polish.<br><span class="zk-mark zk-mark--pink">More person.</span></h1>

A pinned note

<div class="zk-note zk-note--mint zk-tilt-left">
  <h2 class="zk-heading">Remember this.</h2>
  <p>Something worth putting on paper.</p>
</div>

Form field

<div class="zk-field">
  <label for="email">Email</label>
  <input id="email" class="zk-input" type="email" autocomplete="email" aria-describedby="email-help">
  <span class="zk-help" id="email-help">Used only for your reply.</span>
</div>

Add aria-invalid="true" for an invalid field, provide a visible error message and link it with aria-describedby. CSS does not validate or submit anything. Use real labels and actual consent wording.

Disclosure

<details class="zk-details">
  <summary>What comes in the box?</summary>
  <p>A stylesheet and a little personality.</p>
</details>

React

import 'zink-css';
export function Note() {
  return <section className="zk"><article className="zk-card zk-taped">
    <h2 className="zk-heading">Made by a person.</h2>
    <p>No special React component needed.</p>
  </article></section>;
}

Vue, Svelte, Astro and plain HTML use the same class names. There is no component runtime or package-specific API.

Make it yours

Override tokens on your wrapper, after importing the stylesheet:

.my-zine.zk {
  --zk-paper: #fff4df;
  --zk-pink: #ff8ab4;
  --zk-yellow: #f7cf31;
  --zk-ink: #211b18;
  --zk-font: Georgia, serif;
  --zk-display: 'Permanent Marker', cursive;
  --zk-space: 1.25rem;
  --zk-measure: 60ch;
  --zk-shadow: 3px 5px 0 var(--zk-ink);
}

Full defaults are at the top of dist/zink.css. Colours, font stacks, space, text measure, border and shadow are custom properties. Changes inherit through your .zk area. Test contrast after changing tokens.

Fonts

The library makes no network requests and bundles no fonts. System monospace and a system handwritten/cursive fallback work out of the box. For the same marker/typewriter feel as the demo, optionally load the open-source Google Fonts Permanent Marker and Courier Prime:

<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Courier+Prime:wght@400;700&family=Permanent+Marker&display=swap">
.zk { --zk-display: 'Permanent Marker', cursive; --zk-font: 'Courier Prime', monospace; }

You can self-host fonts instead, subject to their own licences. The optional Google Fonts request is your choice, not a dependency of the CSS kit. The demo's exact appearance depends on those fonts; fallback faces differ by OS.

Accessibility and browser support

Native HTML, visible keyboard focus, 44px button/input targets, wrapped text and responsive layouts. Reduced-motion preference removes button movement/transition. Forced-colour mode removes decorative backgrounds/tape where needed. Print rules remove texture/rotation/shadows. Disabled buttons stay disabled. No flashing effects or automatic animation.

Modern evergreen browsers are the target. Uses CSS custom properties, :where, :focus-visible, clamp, grid, min() and gradient backgrounds. Functional graceful degradation is expected where decorative clip paths or box-decoration-break are unavailable. Visual tests run in Chrome; Firefox/Safari are not independently verified in this release candidate. This kit is not a WCAG compliance guarantee. Site authors still own semantics, colour customisation, validation and behaviour.

Local demo and checks

npm test
npm run pack:check
python3 -m http.server 8080
# open http://localhost:8080/demo/

No build needed. dist/zink.css is the canonical, readable production stylesheet. Test scripts use Node's built-in runner; there are no dev dependencies. examples/components.html shows the remaining elements.

Publishing checklist (owner-run)

  1. Confirm zink-css is still available and npm account has permission. This name is not reserved.
  2. Review package identity, MIT licence, optional font terms and screenshots. Add author/repository metadata if desired; none is guessed.
  3. Run tests and inspect npm pack --dry-run. demo/ and tests/ stay out of the published tarball; examples/docs/CSS are included.
  4. Authenticate in the owner's terminal, with 2FA as required. Never put tokens in files or chat.
  5. Publish only after owner approval.

Licence

MIT for the original CSS, docs and demo code. Third-party fonts are not included in the library and retain their own licences. No artwork or quote collection from Siva's portfolio is bundled.