Design System · v3.1 · Village-forward · Themeable · Repo-aligned
Not Every Mom Design System
Rooted in the Village — warm, paper-tinted, analog. The visual
language of Kindred Mama: the M.O.M AI companion and peer
community for cycle-breakers. Parchment textures, handwritten warmth,
ceramic mugs, candlelit circles. Token-aligned to the repo's
index.css with canonical dark mode via
.dark class.
Source: kindred-mama-aiType: Playfair Display + InterRadius: 12px systemGround: Library · Kitchen · Grove · Shore · DuskSkins: 10 (5 feels × light/dark)Base: 18px (accessibility-driven)Dark: .dark class (repo) + feel layers
Architecture & Handoff
00 · Foundation
How tokens, dark mode, feel modes, and persona themes compose. This
section is the engineering contract — read it before touching any
component code.
Three-layer stack
Every surface in the product is determined by three composing layers.
Higher layers override lower ones. Components should read semantic
tokens — never hardcode hex values.
Layer 3 — theme-system.js
Feel-mode cosmetics (Library, Kitchen, Grove, Shore, Dusk)
Canonical dark-mode token overrides from tokens.css
Core
Flips ALL semantic tokens (background, foreground, card, border,
muted, persona adjustments). Tailwind
dark: prefix keys
off this class. Works standalone — no JS required.
Layer 1 — :root
Light-mode defaults in tokens.css
Foundation
Brand colors, semantic tokens, persona palettes, sidebar tokens,
gradients, shadows, radius, motion, type. The ground truth.
Persona theming — data-theme attribute
When a persona is active, set
[data-theme="rose|vera|betsy|hazel"] on the
root or a scoped container. This remaps
--primary,
--secondary, and
--ring to the persona's palette. Works in
both light and dark — the .dark class
includes adjusted persona values.
data-theme="rose"
--primary → 15 85% 65%
data-theme="vera"
--primary → 152 45% 35%
data-theme="betsy"
--primary → 186 60% 55%
data-theme="hazel"
--primary → 270 65% 60%
New tokens added in v3.1
Sidebar tokens (8 vars)
--sidebar-background · 40 20% 97%
--sidebar-foreground · 25 51% 13%
--sidebar-primary · 200 35% 70%
--sidebar-primary-foreground · 25 51% 13%
--sidebar-accent · 152 18% 32%
--sidebar-accent-foreground · 0 0% 100%
--sidebar-border · 200 20% 85%
--sidebar-ring · 200 35% 70%
Status foreground variants
--destructive-foreground · 0 0% 100%
--success-foreground · 0 0% 100%
--warning-foreground · 25 51% 13%
--info-foreground · 25 51% 13%
Accessibility tokens
--focus-ring-width · 2px
--focus-ring-offset · 2px
Glass effects
--iridescent-gradient
Accessibility media queries
prefers-reduced-motion: reduce
All transitions and animations are killed.
--transition-gentle and
--transition-bounce resolve to
none.
prefers-contrast: high
Borders darken, foreground/muted-foreground strengthened for both
light and dark. Ensures WCAG AAA compliance for text.
Tailwind integration notes
For Claude Code / engineering handoff
The repo uses Tailwind utilities +
hsl(var(--token)) for styling. Our
prototype components use inline React
style={{}} with the
$t('--token') helper. To bridge:
All tokens in tokens.css use the
Tailwind H S% L% convention (no
hsl() wrapper).
The .dark class provides canonical
dark overrides — Tailwind's
dark: prefix keys off this.
[data-theme] persona overrides remap
--primary/--secondary/--ring and work
in both light and dark.
Feel modes (Library → Dusk) are a progressive enhancement. The
product works without theme-system.js.
When migrating a component: replace
$t('--token') calls with Tailwind
utilities like
bg-primary text-primary-foreground.
File manifest
tokens.css
Layers 1 + 2. All custom properties. No runtime dependency.
Mobile Colors.ts uses
#0D2D2D /
#F7FBFC as dark/light backgrounds —
different from web's hsl(189 100% 96%) /
hsl(152 18% 8%). These should converge.
Track in product backlog.
Brand
01 · Identity
The brand mark is a wreath of barbed wire intertwined with
forget-me-not flowers — thorns and beauty held together. A small bee
nestles in the blossoms. The wordmark sits center in Playfair Display.
Light surface · #F8F4ED
Dark surface · #2D1309
Voice & tone
Product voice
Warm, unhurried, non-clinical. Writes like a trusted friend who
has been through a lot. Validates before advising. Never uses
"just" or "simply". Textures over platitudes.
M.O.M voice
Specific, present, grounded.
"That sounds like it's been heavy to carry." ·
"I'm here. Take your time." · Variable latency — mirrors
your rhythm, never rushes.
Photography & Illustration
02 · Visual Assets
The photographic direction is warm, analog, and intimate. Ceramic
mugs, wooden tables, natural light, handwritten journals. Never
clinical, never stock. People are shown in
private moments of quiet courage — reading, writing, reaching
across a table.
Emotional JourneyFeature section, about pageemotional-journey-hero.jpg
Line art illustrations
Single-stroke organic illustrations in brand colors. Used as
decorative accents, section dividers, and persona identifiers. Never
fill — always line weight only.
Birch Leaf
Crescent Moon
Mother & Child
Heart in Hand
Flowing Waves
Textural asset
Chat Patternchat-pattern.png
Photo direction rules
Do: Warm natural light, wooden surfaces, ceramic objects,
handwritten text, green plants, linen textures, candlelight, steam
rising from mugs.
Don't: Stock smiles, clinical settings, bright studio
lighting, pristine surfaces, group shots facing camera, children's
faces.
Palette range: Amber → sage → warm brown. The photography
should feel like it lives inside the "Kitchen Table" feel mode.
Color
03 · Tokens
Five brand colors anchor the system. The palette is pulled from the
photography — warm wood, old parchment, pressed sage, the blue of
forget-me-nots. Every color should feel like it could exist in a cabin
kitchen.
Powder Blue--powder-blue#97B8CB · 200 35% 70%
Muted Gold--muted-gold#D99F60 · 34 41% 61%
Dark Brown--dark-brown#2D1309 · 25 51% 13%
Light Cyan--light-cyan#EDFDFF · 189 100% 96%
Deep Green--deep-green#415B4F · 152 18% 32%
Semantic roles
background
foreground
primary
secondary
accent
muted
card
border
input
ring
destructive
success
Extended Village palette
Colors derived from the Village photography. These warm the base
palette toward the paper-tinted, parchment aesthetic.
The whole product ships five mood variants. Same IA, different
texture. Each shifts card backgrounds, paper tints, accent lines, and
page warmth. Not a recolor — a mood. Set via
tweaks.feel. The Library mood is the
default.
Warm table. Deeper amber, toasted borders.
"Around the kitchen table."
page #f9f2e6accent #c88548
Grove
Held by earth. Sage-green, mossy edges. "In the grove."
page #f2f6efaccent #5b8a63
Shore
Quiet blue calm. Powder blue, sea-glass.
"At the water's edge."
page #eff7faaccent #7daebe
Dusk
Soft lavender. Purple stillness.
"When the light goes low."
page #f5f1f9accent #9882b0
Persona Themes
05 · Characters
Four AI personas, each with a distinct color gradient, specialty, and
voice. Personas don't post in the Village — they read it to
surface relevant threads in 1:1 chat.
The grounded one. Forest tones, sage accents. Holds space
without rushing.
Betsy
Calming clarity · practical care
The clear one. Teal tones, aqua accents. Practical warmth,
straight talk.
Hazel
Loving intuition · deep knowing
The intuitive one. Purple-lavender tones. Sits with the unsaid.
Typography
06 · Type System
Playfair Display for headings — literate warmth, editorial weight.
Inter for body — clean, readable, unhurried. The pairing reads like a
private journal: handset titles, careful running text.
DisplayPlayfair 500 · 72px
Not Every Mom
H1Playfair 500 · 48px
Breaking the cycle
H2Playfair 500 · 36px
The Village
H3Playfair 500 · 28px
Story Circles
LedeInter 300 · 20px
A peer community for cycle-breakers. Anonymous by default. Held
gently.
BodyInter 400 · 18px (base)
My mother asked for the fourth time why I haven't visited. Usually
I spiral into a paragraph of reasons. This week I sent six words.
SmallInter 400 · 14px
Safety 4.9 · held by 4 mods today · 3 new threads since your last
visit
EyebrowInter 600 · 11px
From today's reading
Surfaces & Texture
07 · Materials
Surfaces draw from the Village's analog world — linen, parchment,
pressed paper. Cards sit on warm paper with soft borders. Backgrounds
use subtle vertical gradients from cream to warm white.
Library Paper
linear-gradient(#fbf8f1, #f6f1e8)
Kitchen Amber
linear-gradient(#fdf3e0, #f6e8cd)
Grove Sage
linear-gradient(#f1f6ee, #e7efe2)
Warm Linen (page bg)
#F8F4ED
Card White
#FFFFFF · border #E7DCC4
Parchment (recessed)
#F2EBE1
Gradients
Primary
--gradient-primary
Subtle
--gradient-subtle
Warm
--gradient-warm
Elevation
08 · Shadows
Gentle0 2px 12px powder-blue/15%
Warm0 8px 32px muted-gold/25%
Premiuminset ring + 0 8px 32px dark-brown/12%
Radius
09 · Corners
4px · sm
8px · md
12px · lg (default)
999px · pill
Motion
10 · Animation
Movement is unhurried. Two easing curves: gentle for most
transitions (0.4s ease-out) and bounce for small interactive
affordances. Hover to preview.
A moderated peer community for cycle-breakers. Anonymous by default.
The Village ships three feel modes, four validation-only reactions,
content warning veils, and a trauma-informed moderation desk. M.O.M
personas don't post — they read to surface relevant threads
in 1:1 chat.
Anonymity treatments
·
Soft Pseudonym
Quiet River
Deterministic pairing of a hushed adjective + nature noun.
Gradient avatar from same hash. Warm and present.
anon: "pseudo"
∅
Stark Anonymous
Anonymous
Null symbol on a flat chip. Maximum anonymity. Product default.
anon: "stark"
QR
Initials
Q R
Initials from pseudonym on a flat circle. Warmer than stark, less
identifying.
anon: "initials"
Content veil (covered state)
estrangement
holiday stress
Held gently. This post mentions estrangement, holiday stress. Only
uncover if you have the room.
Thread card specimen
BoundariesPinned
I sent the text. I did not soften it.
My mother asked for the fourth time why I haven't visited. Usually I
spiral into a paragraph of reasons. This week I sent six words.
Quiet River · 12m
18
replies41 reactions
Safety pulse
Safety 4.9 · held by 4 mods today
Forum rooms
Boundaries
The hard "no"
Reparenting
What you didn't get
Estrangement
No-contact grief
Triggered
Breaking mid-cycle
Moderation queue — 3-tier AI pre-screen
T1
Safe · 94%boundaries · 24m
I wrote the text but haven't sent it. How do you know when it's
ready?
T2
Questionable · 71%
crisis
I feel like I'm disappearing inside my own house…
T3
Dangerous · 88%
[handed to Crisis Protocol]
Handed off
Dark Mode
18 · Night Surface
Dark mode isn't an afterthought — it's a first-class skin. For a
product that people use late at night, in bed, processing hard
feelings, the dark surface should feel like a held space: warm dark
browns, never blue-black. Core dark mode uses the repo's
.dark class (Layer 2 in tokens.css). Every
feel mode layers its own dark variant on top (Layer 3 via
theme-system.js).
Dark surface tokens
Page Background
#1A1614
Card Surface
#24201D
Recessed
#1E1A17
Border
#3A332C
Dark text hierarchy
PrimaryNot Every Mom
SecondaryA peer community for cycle-breakers
MutedSafety 4.9 · held by 4 mods today
AccentFrom today's reading
Dark feel variants
Dark Library
Brown-black · gold
Dark Kitchen
Amber-dark · toasted
Dark Grove
Deep green · sage
Dark Shore
Deep sea · powder
Dark Dusk
Deep purple · lilac
Dark component specimens
Rose · M.O.M
That sounds like it's been heavy to carry.
I told my daughter it was okay to cry.
Boundaries
I sent the text. I did not soften it.
Quiet River · 12m · 18 replies
Try it live
Use the theme switcher (bottom-right of this page) to toggle dark
mode. The entire design system skins itself. Your choice persists
across sessions.
Resources
19 · Reflective Surface
Not a library. Not a content feed. A reflective surface — what the
oracles know about you, expressed as the things placed in front of you
today. Mneme is felt, not seen: the hero reading wasn't chosen
by category, it was placed by oracle state.
Oracle-placed reading — hero card
The top card is always a single article placed by the oracle engine
based on emotional arc, topic salience, and life season.
Rose placed this · today
CPTSD Foundation · 8 min
The Grief That Has No Funeral
"You mentioned Dana hasn't called back. I read this and thought of
you — not because it fixes anything, but because the writer names
the specific kind of quiet you described."
Read
Persona voice attribution
Persona voice ON
Why Rose left this
AI
"The guilt after holding a line — you keep circling back to it.
This might help you stop treating guilt as a verdict."
Persona voice OFF
Why setting a boundary with a parent activates guilt that feels
like proof you've done something wrong — and why that feeling is
inherited, not earned.
Topic stacks
The Mother Wound
12 resources
Boundaries & Safety
8 resources
Reparenting
6 resources
Validation
4 resources
Journal prompts
Reparenting
"Write a letter to the child you were. What did she need to hear?"
Boundaries
"Name one boundary you held this week. How did your body feel
after?"
The Mother Wound
"What is one thing your mother taught you — by negative example?"
Validation
"Describe a moment this week where you chose differently than she
would have."
Crisis lines — always one gesture away
A quiet "Crisis lines · 24/7" button is always visible in the
Resources masthead.
Crisis Text Line
Text HOME to 741741 · 24/7
988 Suicide & Crisis Lifeline
Call or text 988 · 24/7
National DV Hotline
1-800-799-7233 · 24/7
Not Every Mom is not a crisis service. If you are in immediate
danger, call 911.
Theme Switcher
20 · Accessibility
A small embedded control lets users choose their skin: 5 feel modes ×
2 brightness levels = 10 skins. The choice persists to
localStorage. The switcher lives inline in
the page header — a subtle dot that expands to reveal color choices
and a light/dark toggle.
How it works
Embedded dot → expanding tray
A 30px circle sits in the page header metadata row. Clicking it
expands a horizontal tray to the right with: two brightness buttons
(☀/🌙) + a separator + five color dots (one per feel mode). The
active feel is shown with a ring; active brightness gets an accent
highlight. Click anywhere outside to collapse.
Inline, not floating30px triggerHorizontal expansionlocalStorage persistence5 color dots
Skin matrix
Library
Kitchen
Grove
Shore
Dusk
Each dot × light/dark = 10 total skins. Try it now — the switcher is
in the header above. ↑