Skip to content
Ahimsa

Foundations

The values, and why each one is what it is

Every swatch and every line below is read out of the shipped token files at build time, so nothing on this page can drift from what you get.

Color

Never pure white, never pure black

The cards are warm paper under a light gray sky with soft white clouds, and the darkest ink is cocoa. Pure black on pure white is a harsher contrast than any screen needs, and it reads as clinical — so the system does not contain either. Night holds the same law from the other end: its deepest ground is #060914 and its lightest ink #e4eef5.

Neutrals — Day

neutral

50 #f7f6f1
100 #f1eee6
200 #ece6dc
300 #e0dbd1
400 #b5aea6
500 #8a8179
600 #5e5149
700 #3a2c25
800 #30221c
900 #1c1410

Neutrals — Night

neutral

50 #e4eef5
100 #d3dfe9
200 #b0bfce
300 #8a9bb0
400 #667790
500 #495771
600 #323f58
700 #1e2940
800 #0f1626
900 #0a1124
950 #060914

Day's accents, the recommended family, are named for the tradition the system takes its ethics from: saffron for renunciate robes, turmeric for ritual gold, clay for earthen lamps, bodhi for the fig tree of awakening, peacock for India's bird, indigo for the Champaran satyagraha crop, monsoon for gray-blue rain skies. Nothing high-chroma, nothing poppy.

Day · the ahimsa-tradition set

saffron

300 #e0c0a3
400 #d4a278
500 #c37a40
600 #b4560d
700 #80400e

turmeric

300 #d4c69f
400 #c0ad72
500 #a58b36
600 #8c6c00
700 #664e05

clay

300 #ddbead
400 #ce9f89
500 #ba7659
600 #a8502e
700 #783c24

bodhi

300 #bfccad
400 #9db789
500 #709a5a
600 #46802f
700 #385b24

peacock

300 #adcbc2
400 #7fb4ac
500 #42968f
600 #0a7a75
700 #105753

indigo

300 #c0becf
400 #9f9ec2
500 #7375b0
600 #4a4fa0
700 #3a3b6f

monsoon

300 #c4c5c4
400 #a5aaaf
500 #7c8793
600 #56677a
700 #424b56

The classic family is the original accent set, kept because a consuming app built a full range of person-gradients directly on it. One rename: its blue-violet is --periwinkle-*, because it used to be called --indigo-* at a different value from the tradition set's indigo, and two different colors cannot share one name.

Day · the classic set

amber

300 #d2c3b4
400 #c3b1a1
500 #b2a496
600 #97897b
700 #786a5d

rose

300 #e0d1d1
400 #d1bbbd
500 #bfa6a9
600 #a2888c
700 #826b6f

terracotta

300 #bfb2ac
400 #ac9b94
500 #97847a
600 #7a695f
700 #5f5148

sage

300 #bfc7c2
400 #a2ada4
500 #849386
600 #6a796d
700 #515f54

violet

300 #cec7d5
400 #bcb4c6
500 #a9a1b6
600 #8f879d
700 #746c81

slate

300 #afb5bd
400 #929ba7
500 #788392
600 #5d6977
700 #49525e

periwinkle

300 #bec0d1
400 #9a9fba
500 #7d82a0
600 #656b88
700 #515571

Night keeps every hue Day chose, anchored on its 300 step where Day anchors on 600, with a lighter 200 because a dark ground needs brighter ink. Only one family is new: frost, the pale ice at the core of every glow. Warnings are clay in both — Low Embers at night — and never red.

The name chosen for each hue, in Day and in Night
TokenDayNight
--saffron-*Marigold RobeGhee
--turmeric-*Gold LeafGold Dust
--clay-*KilnLow Embers
--bodhi-*Young LeafFig Leaf
--peacock-*VerdigrisGlacier Lake
--indigo-*ChamparanNila
--monsoon-*Rain CloudRain Cloud

Night

saffron

200 #ecd4b3
300 #e8b878
400 #c09a69
500 #9d7f5b
600 #79654e
700 #5a4d42

turmeric

200 #eee3b5
300 #ecd47a
400 #c3b16b
500 #9f925d
600 #7b734f
700 #5b5743

clay

200 #e9c7bb
300 #e3a086
400 #bc8674
500 #996f65
600 #775955
700 #584447

bodhi

200 #b2d9c0
300 #7ec18f
400 #69a17c
500 #57856b
600 #44695a
700 #34504b

peacock

200 #b2e1e8
300 #7fd0d8
400 #6aaeb8
500 #578f9b
600 #45717e
700 #345665

indigo

200 #c4cbf8
300 #a0a8f5
400 #858dcf
500 #6d75ae
600 #555d8d
700 #40476f

monsoon

200 #c6d4e3
300 #a3b8cf
400 #879ab0
500 #6f7f95
600 #57657a
700 #414d62

frost

200 #e4f1f5
300 #c3e2ea
400 #9ccfdb
500 #74b8c8
600 #549cad
700 #3d7c8c

Gradients

One gradient owns a screen

All of them run at 155°, with stops at 0 / 30 / 60 / 100%. They are moments of emphasis, not decoration. The sky behind a Day screen and the stars behind a Night one are the ground, not a gradient of their own. Two gradients side by side is the rule this system breaks least gladly.

Each one ships as .ah-surface--<name>, which sets the gradient and the ink measured to work on it. A 155° ramp spans a wide lightness range, so no single ink can carry text across all of it; the surface therefore carries its own. A gradient that cannot clear AA at any ink opacity is marked surface-only — put text on them in an opaque card, which is this system's pattern anyway.

Day

sky

carries text

dawn

carries text

cream

carries text

sun

carries text

saffron

carries text

turmeric

carries text

clay

carries text

bodhi

carries text

peacock

carries text

indigo

surface only — text goes in a card

monsoon

carries text

amber

carries text

rose

carries text

coral

carries text

terracotta

carries text

sage

carries text

teal

carries text

violet

carries text

slate

carries text

periwinkle

carries text

periwinkle-soft

carries text

mauve

carries text

olive

carries text

Night

deep

carries text

midnight

carries text

horizon

carries text

aurora

carries text

iris

carries text

nightfall

carries text

ember

carries text

void

carries text

Type

Two voices, and the split is the tone

Both aesthetics pair Fraunces, a variable serif carrying emotional weight, with DM Sans for utility. The type is the same in Day and Night on purpose: a person moving between them has not moved between two products. An emotional line is set apart in italics and a factual line stays plain.

The size scale is musical and deliberately uneven — there is no 12px and no 14px. It is expressed in rem at the same computed sizes it has always rendered, so raising your browser's font size actually works.

Display XL · .ah-display-xl

Nothing here is designed to grab you.

A screen that is mostly one sentence.

Display L · .ah-display-l

Nothing here is designed to grab you.

Display M · .ah-display-m

Nothing here is designed to grab you.

Heading L · .ah-heading-l

Nothing here is designed to grab you.

Heading M · .ah-heading-m

Nothing here is designed to grab you.

Title L · .ah-title-l

Nothing here is designed to grab you.

Title M · .ah-title-m

Nothing here is designed to grab you.

Prose · .ah-prose

Nothing here is designed to grab you.

Running text. 1rem, and the only size long copy may use.

Body · .ah-body

Nothing here is designed to grab you.

A UI label size. Not for paragraphs.

Body serif · .ah-body-serif

Nothing here is designed to grab you.

Caption · .ah-caption

Nothing here is designed to grab you.

Label · .ah-label

Nothing here is designed to grab you.

The two signature styles

Small caps · the utility voice

A supporting line, quietly offered.

Wide-tracked uppercase for what is known; the emotional register for what is felt. Never quotation marks on a pull quote — the setting is already doing that job.

Fluid display

Begin

Day pulls display type tight (-0.045em); Night opens it out (+0.03em). Same class, opposite gesture.

Space

A 4px grid, composed like a magazine

The grid is mechanical; the composition is not. Generous negative space is a principle, not a preference: at least one full unit of air above and below a heading, and if a section feels crowded, remove elements before shrinking type.

Spacing scale

--space-0
0px
--space-1
4px
--space-2
8px
--space-3
12px
--space-4
16px
--space-5
20px
--space-6
24px
--space-7
28px
--space-8
32px
--space-10
40px
--space-12
48px
--space-16
64px
--space-20
80px
--space-24
96px

Radius — rounded at every scale, never sharp

xs
sm
md
lg
xl
2xl
3xl
full

Sharp corners in an interface carry an implicit threat; rounded corners carry receptiveness. This is a system law rather than a Day preference, which is why Night's radii are identical.

Elevation

Paper in Day, light in Night

Day's shadows are warm brown-tinted and layered, never harsh and never black. --shadow-md carries an inner white highlight, and that highlight is what makes a card read as paper rather than as a floating rectangle.

Night cannot use shadow — a drop shadow is invisible on a dark ground. The same token names do a different job there: an inset hairline ring establishes the edge, an inner top highlight suggests a lit surface, and emphasis comes from --glow-* rather than from a brighter fill.

The shadow scale

xs
sm
md
lg
xl

Motion

Settling, not pouncing

Nothing snaps and nothing overshoots. Every easing curve in the system ends at 1.0 with no value above it, which is a mechanical guarantee that no transition can bounce. A press shrinks by 3%; a sheet rises over 550ms and decelerates into place. Motion mimics settling, not predator movement.

Durations and easings

TokenValueFor
--duration-instant100msthe smallest acknowledgements
--duration-fast200mshover and press
--duration-base300msstate changes
--duration-slow400mscard flips
--duration-slower550mssheet slide-ups
--duration-slowest800msonboarding transitions
--duration-reveal620msclip-path wipes of a large surface
--ease-standardcubic-bezier(0.4, 0.0, 0.2, 1.0)small state changes
--ease-emphasizedcubic-bezier(0.32, 0.72, 0.32, 1.0)carousels, card reveals, sheets
--ease-deceleratecubic-bezier(0.0, 0.0, 0.2, 1.0)anything entering
--ease-acceleratecubic-bezier(0.4, 0.0, 1.0, 1.0)anything leaving
--ease-revealcubic-bezier(0.76, 0, 0.24, 1)clip-path wipes
--ease-expocubic-bezier(0.22, 1, 0.36, 1)a long, soft settle

Under prefers-reduced-motion the system removes animation outright rather than shortening it — and it does not lower durations, because reduced motion must not mean slower or less legible, only stiller.

Ambient

Night's field, and why it asks for nothing

Night ships an optional decorative layer: a dark field with additive bloom, film grain, scanlines, a vignette, and line geometry. The references for it are WebGL pieces with a full postprocessing chain — but additive blending is mix-blend-mode: plus-lighter, noise is feTurbulence, scanlines are a repeating gradient, and RGB shift is a per-channel feOffset. None of it needs a renderer, a canvas, or a byte of JavaScript.

The quietest layer is .ah-ambient--stars: a faint, static field of stars in a fixed arrangement, so the sky is the same every night. It does not twinkle and it never moves. Day has its counterpart in .ah-sky, a light gray sky with three large, soft white clouds that never move. Both are the ground a screen sits on, and neither carries meaning.

The layer, composed

ambient · decorative · aria-hidden

It has nothing to tell you.

Switch to Night to see it against the rest of the system.

Hard constraints, not stylistic ones

  • It never encodes state or progress. Nothing can be missed by ignoring it.
  • It never reacts to error. A glitch effect on failure tells someone their screen is broken.
  • It never flashes. Nothing pulses faster than 0.1Hz and no animation is shorter than 2s — well outside WCAG 2.3.1's three-flash threshold.
  • It animates opacity and hue only, never position. Movement in peripheral vision is a demand for attention.
  • It disappears entirely under prefers-reduced-motion, prefers-reduced-transparency, and forced-colors.

Spectacle that asks for nothing is the only kind this system allows. tools/check-attention.mjs enforces the timing and the no-transform rule.