Skip to content
Ahimsa

For agents

Building with Ahimsa, without a person in the loop

This page is the short brief. If you are an agent generating an interface, you need three things: the token vocabulary, the class vocabulary, and the list of things you must not produce.

Setup

What to load

ahimsa-design/
  dist/ahimsa-day.css      one aesthetic, flattened, self-contained
  dist/ahimsa-night.css    the other
  dist/ahimsa.css          both, switch with a class on <html>
  dist/CHECKSUMS           sha256 per file, for a pinned vendored copy
  fonts/                   4 woff2 + 2 OFL license texts — copy all of it
  tokens.json              every token, W3C DTCG format, both themes
  SKILL.md                 this brief, in full

Link one stylesheet, put class="ahimsa-day" or class="ahimsa-night" on <html>, and copy fonts/ next to it. Never load a font or a script from a CDN.

Vocabulary

Reference semantics, never raw palette steps

A component must never reach for --saffron-600 or --neutral-200 directly. Use the semantic layer, which both aesthetics define with identical names — that is the entire reason markup is theme-portable.

surfaces   --surface-canvas  --surface-elevated  --surface-sunk  --surface-inverse
text       --text-heading  --text-body  --text-secondary  --text-muted  --text-inverse
borders    --border-subtle  --border-medium  --border-strong  --border-control
accents    --accent-primary  --accent-secondary  --accent-success  --accent-warning
focus      --focus-ring  --focus-ring-width
glass      --glass-overlay  --glass-overlay-strong  --glass-scrim  --glass-blur
depth      --shadow-xs..xl  --shadow-sheet  --glow-sm  --glow-md  --glow-lg
space      --space-0..24          radius  --radius-xs..3xl  --radius-full
type       --size-micro..5xl  --size-reading  --font-display  --font-body  --font-mono
motion     --duration-*  --ease-*

Three that will catch you out

--border-control, not --border-strong, for the edge of an interactive control. The former clears 3:1; the latter is a decorative separator and deliberately does not.

--size-reading, not --size-base, for running prose. --size-base is a UI label size.

--glow-* is none in Day. Reference it unconditionally; it does the right thing in both.

Vocabulary

The class list, complete

actions    .ah-btn [--sm --ghost --glass --danger --wide]  .ah-pill [--outline --glass --static]
           .ah-link [--quiet]  .ah-actions  .ah-hit
forms      .ah-field [--essence]  .ah-field__label  .ah-field__help  .ah-chip
surfaces   .ah-card [--list --sunk --glass --flat --p0]  .ah-scrim  .ah-sheet
           .ah-sheet__grab  .ah-sheet__head  .ah-sheet__title  .ah-sheet__close
display    .ah-caps [--micro --rule]  .ah-quote [--md --xl --bordered]
           .ah-mono [--sunk --glass --s20..s144]  .ah-dots  .ah-sdot  .ah-rule-row
feedback   .ah-toast  .ah-notice [--warning]  .ah-notice__title  .ah-notice__row
type       .ah-display-xl/l/m  .ah-heading-l/m  .ah-title-l/m  .ah-body  .ah-body-serif
           .ah-prose  .ah-caption  .ah-pull-quote  .ah-label  .ah-small-caps  .ah-micro-caps
           .ah-display-fluid
layout     .ah-page  .ah-measure  .ah-stack  .ah-section  .ah-app  .ah-screen  .ah-scroll
           .ah-hdr  .ah-footer  .ah-list  .ah-hrow
surface    .ah-surface--<gradient>     ambient  .ah-ambient--<void|bloom|grain|scan|vignette|grid|isolines|horizon>
state      .is-active  .is-selected  .is-disabled  .is-tappable  .is-on

State is .is-*; variants are --modifier. Anything not on this list does not exist — do not invent .ah-alert or .ah-badge, because those are the two the system specifically refuses.

Constraints

Not negotiable

  1. Emit nothing that appears on its own. No alert(), no modal on load, no banner, no toast that is not the direct consequence of an action the person just took, no role="alert", no aria-live="assertive", no setInterval, no autoplay, no beforeunload.
  2. Never emit red. There is no red token. If you are reaching for one, the thing you are building is probably refused for a second reason too.
  3. Every destructive or leaving action gets an equal-weight escape. .ah-btn beside .ah-btn.ah-btn--ghost, labeled warmly.
  4. Every interactive element is a real element with an accessible name, reachable by keyboard, at a 44px target, acting on pointer-up.
  5. Never disable pinch zoom. No maximum-scale, no user-scalable=no.
  6. Never load anything over a network. No CDN, no Google Fonts, no remote @import.
  7. One gradient per screen, via .ah-surface--<name> so the ink comes with it.
  8. Run the gates. npm run check will fail on most violations of the above, which is the point of it existing.

If a requirement you have been given conflicts with one of these, say so rather than resolving it quietly. The conflict is usually the most useful thing you have found.

Copy

Write it like this

Continue / Not now              not  CONTINUE / cancel
Keep it / Delete it             not  Are you sure?
3 remaining                     not  Only 3 left!
A quiet place to begin.         not  Get started now — don't miss out!
Ready for your calendar         not  Added!
That did not go through. Nothing was changed.
                                not  Error: INVALID_INPUT. Please try again.

Sentence case. No exclamation marks, no ALL-CAPS, no emoji. Short declarative sentences. When something fails, say what is still true.