0. Design Principles

The memax design philosophy. Read this first — every token, component, and pattern decision flows from these 8 rules.

LLM Agent Reference — structured rules for code generation

If you are an AI agent generating memax UI code, these are the hard rules. Each rule maps to a section. Violating any rule produces non-memax output.

MEMAX DESIGN SYSTEM — HARD RULES FOR CODE GENERATION
═══════════════════════════════════════════════════════

COLORS (§13)
  text:       text-fg-1 (titles, body) | text-fg-2 (secondary) | text-fg-3 (meta) | text-fg-4 (decorative)
  surfaces:   bg-surface-1 (subtle) | bg-surface-2 (hover) | bg-surface-3 (active)
  accent:     var(--signature) — ONLY for AI indicators (✦), never decorative
  NEVER:      text-gray-*, bg-gray-*, hardcoded colors, text-foreground/XX

TYPOGRAPHY (§12)
  H1:         text-[21px] font-bold                    (one per view, memory detail title)
  H2:         text-[16px] font-bold                    (section headers)
  H3:         text-[14px] font-semibold                (card titles)
  body:       text-[14px] text-fg-1                    (default)
  secondary:  text-[13px] text-fg-2 or text-fg-3       (descriptions, meta)
  caption:    text-[12px] text-fg-3                    (timestamps, category)
  micro:      text-[10px] text-fg-4 uppercase tracking-wider font-semibold (group headers)
  weights:    400-700 only. NEVER font-light (300) or font-black (900)
  prose:      leading-[1.65] for AI answers and readable paragraphs

SURFACES (§14)
  card grid:  <Surface variant="default">             (bar-border + bar-shadow)
  detail:     <Surface variant="subtle" rounded="2xl"> (border only)
  mobile:     <Surface variant="borderless">           (full bleed)
  minimal:    <Surface variant="clean">                (bg only)
  radius:     bar/modal 16px → card 12px → button 8px → nested 6px

LAYOUT (§20)
  page:       max-w-4xl mx-auto px-5 sm:px-8 pb-36 md:pb-32
  top:        paddingTop: CONTENT_TOP (80px desktop)
  entrance:   animate-content-ready (on every page load)
  bar:        fixed bottom center, z-50, max-w-[640px]
  modal:      z-65 content, z-60 backdrop

MOTION (§18)
  easing:     var(--ease-spring) — cubic-bezier(0.16, 1, 0.3, 1)
  NEVER:      linear, ease-in-out, ease
  fast:       0.15s (hover, modal, dropdown)
  normal:     0.2s (content transitions)
  AI breathe: state-slow-breathe (2.5s loop)
  entrance:   animate-content-ready (0.15s opacity + translateY)

CONTROLS (§19)
  buttons:    <Button variant="default|outline|secondary|ghost|destructive">
  sizes:      xs (h-6) | sm (h-7) | default (h-8) | lg (h-9)
  icon:       icon-xs (24px) | icon-sm (28px) | icon (32px) | icon-lg (36px)
  send btn:   h-8 w-8 rounded-lg. Push=foreground fill, Recall=signature fill
  toggle:     w-10 h-6 rounded-full. On=signature, Off=transparent+border

ACCESSIBILITY (§27)
  fg-1:       12.2:1 — safe everywhere
  fg-2:       5.2:1  — safe everywhere
  fg-3:       2.5:1  — meta/labels only, FAILS AA normal text in light mode
  fg-4:       1.5:1  — decorative only, NEVER readable text
  focus:      focus-visible:ring-3 focus-visible:ring-ring/50
  touch:      44px primary, 32px secondary, 24px minimum
8 principles
01
Opacity, not colors

All text and surface colors derive from --foreground via opacity. Never hardcode color values in components.

Why: One variable change updates the entire palette. Dark mode, themes, and accessibility come free.

text-fg-2 (65% opacity) instead of text-gray-500
02
Container morphing

The same container adapts to different states. Never overlay when the surface can transform.

Why: Overlays break spatial continuity. Users lose context when content jumps between surfaces.

Memory card morphs into detail view — no modal popup, no new page.
03
Signature = intelligence

Dream Violet (--signature) appears only where memax AI is actively working. Never decorative.

Why: If signature color is everywhere, it means nothing. Scarcity creates meaning.

✦ star breathes during AI streaming, static when complete. Never on borders or backgrounds.
04
No sidebar, no top bar

Floating bottom bar, centered content. Tree navigation is peek-on-demand, not always visible.

Why: Maximum content density. The bar is the only persistent UI element.

Bar: fixed bottom center (z-50). Content: scrolls freely with max-w-4xl.
05
Spring easing always

Use var(--ease-spring) for all transitions. Never linear, never ease-in-out.

Why: Spring easing (fast start, gentle settle) creates the memax feel — responsive, alive, never sluggish.

cubic-bezier(0.16, 1, 0.3, 1) for all UI motion.
06
Shape before content

Skeletons mirror the final layout exactly. Loading states show shape, not spinners.

Why: The brain anchors to layout. When content loads into the same shape, it feels instant.

Shimmer skeleton with dot+title+body matches loaded MemoryRow.
07
Spacing creates hierarchy

Use spacing and opacity to separate sections. Never add visible dividers or accent borders.

Why: Dividers add visual noise. Whitespace is a stronger (and quieter) grouping signal.

divide-border/20 (barely visible) or gap spacing, never border-l-4 colored accent.
08
Mobile-first, keyboard-ready

Default styles are mobile. Add sm:/md:/lg: for larger screens. Never block keyboard handlers behind isMobile.

Why: Touch targets and keyboard shortcuts coexist. isMobile is for visual hints only, never for disabling functionality.

Mobile: pill chips (44px touch). Desktop: text toggle. Both work with keyboard.
The memax feel
Quiet

No visual noise. Opacity hierarchy instead of color variety. Whitespace instead of dividers. The content breathes.

Alive

Spring easing on everything. ✦ breathes when AI works. Containers morph instead of swapping. Nothing feels static or dead.

Confident

One accent color, used sparingly. No gradients, no decorative elements. The product gets out of the way. Content is the hero.

Anti-patterns — never do this
BadGoodWhy
text-gray-500text-fg-3Gray doesn't adapt to dark mode or themes
ease-in-outvar(--ease-spring)Feels sluggish and generic
border-l-4 border-blue-500Surface variant + shadow liftColored accent lines are not memax
bg-gray-100bg-surface-1Surface tokens adapt to any theme
shadow-mdvar(--bar-shadow)Bar shadow is a composed, branded shadow
rounded-md (6px) on cardsrounded-xl (12px)Cards use card radius, not component radius
Modal overlay for editingInline transform / morphContainer morphing principle
Spinner for loadingSkeleton shimmerShape before content principle
text-foreground/40text-fg-3Use semantic tokens, not raw opacity
font-light (300)font-normal (400) minimumProduct uses 400-700 weight range only
Quick reference — where to find what

Foundations

Colors → Section 13

Typography → Section 12

Surfaces → Section 14

Spacing → Section 20

Motion → Section 18

Branding → Section 11

Components

Buttons/Badges → Section 19

Indicators → Section 17

State Machine → Section 16

Loading → Section 08

Empty States → Section 09

File map — source of truth
globals.css— all CSS custom properties (tokens)
ui/button.tsx— Button (CVA variants + sizes)
ui/badge.tsx— Badge (CVA variants)
ui/surface.tsx— Surface (5 container variants)
ui/tag.tsx— Tag (removable pill)
ui/skeleton.tsx— Skeleton (loading placeholder)
ui/memax-loader.tsx— MemaxLoader (signature dots)
lib/motion.ts— JS timing constants
lib/category.ts— Category dot colors

11. Branding

Logo wordmark, icon at multiple sizes, and loader variants.

Wordmark (icon + text)
memax

Light

memax

Dark

Icon only

48px

32px (favicon)

20px (nav)

48px dark

MemaxLoader

inline

compact

Loading...

with label

3 dots in signature color, sequential pulse. Pure CSS — no requestAnimationFrame.

13. Color Tokens

Semantic color system built on oklch opacity architecture. All derived from --foreground, adapts to any theme or dark mode automatically.

Architecture — how colors are computed
--fg-1: oklch(from var(--foreground) l c h / var(--op-primary));
--surface-1: oklch(from var(--foreground) l c h / var(--op-bg-subtle));

All semantic colors are computed from --foreground with opacity multipliers. Change one variable, entire palette adapts. No hardcoded color values in components.

Foreground scale — text colors
Aa
Primarytext-fg-1

Titles, body, input text

/90
Aa
Secondarytext-fg-2

Descriptions, placeholders, secondary labels

/65
Aa
Tertiarytext-fg-3

Timestamps, meta, muted labels

/40
Aa
Decorativetext-fg-4

Hints, annotations, divider text

/20
Surface scale — background fills
Subtlebg-surface-1

Slight tint, chip background, hover hint

/3
Hoverbg-surface-2

Hover state, selected row, active tab

/5
Activebg-surface-3

Active/pressed state, strong selection

/8

Stacking demo

surface-1 (subtle tint)
surface-2 (hover)
surface-3 (active)
Theme primitives — light / dark values
TokenLightDarkUsage
--background
#fafafa
oklch(0.155 0.01 260)Page background
--foreground
#1c1c1e
oklch(0.985 0 0)Primary text base
--card
#ffffff
oklch(0.2 0.008 260)Card, bar, modal surfaces
--border
#e5e5e5
oklch(0.275 0 0)Card borders, separators
--muted
#f2f2f2
oklch(0.269 0 0)Summary callouts, subtle bg
--destructive
#ff3b30
oklch(0.704 0.191 22)Error, delete states
--primary
#000000
oklch(0.922 0 0)Primary button, CTA fill
--secondary
#e8e8e8
oklch(0.269 0 0)Secondary button, modal header
Live swatches (adapts to current theme)

Background

--background

Card

--card

Foreground

--foreground

Border

--border

Muted

--muted

Destructive

--destructive

Primary

--primary

Secondary

--secondary
Signature color — Dream Violet
Dream Violetoklch(0.62 0.16 290)

The memax intelligence marker. Appears only where memax is actively working — never decorative, never structural.

Allowed usage

✦ star indicator (AI intelligence marker)
Loading pulse dots (MemaxLoader)
Active nav dot in tree panel
Toggle switch on-state fill
Drag-drop border hint
Recall mode send button fill

Never use for

Decorative borders or backgrounds

Regular button fills or highlights

Text color for non-AI content

Branding outside the app

--signature-muted

oklch(signature / 0.12) — subtle tint for backgrounds

Bar-specific tokens
--bar-borderBar border color (12% opacity)
--bar-shadowBar shadow (layered: outline + medium + large)
--bar-bgBar background (falls back to --card)
Category dots — 13 categories, 4 groups
KnowledgeWhat you know
coreArchitecture, APIs, systems
referenceDocs, guides, specs
decisionsADRs, tradeoffs
ActivityWhat happened
processWorkflows, how-to
dailyStandups, logs
meetingsNotes, agendas
PeopleWho and what they said
chatConversations
contactsPeople, teams
clientsFeedback, reqs
GrowthLearning and building
personalIdeas, reflections
learningCourses, books
researchFindings, hypotheses
projectsPlans, status

Source: lib/category.ts. Colors are frontend-only — backend classifies, frontend renders the dot. Dot size: 6px (w-1.5 h-1.5) in memory rows, 8px (w-2 h-2) in detail view.

12. Typography

Complete type system. Every text element maps to a CSS variable + Tailwind class. 7-step scale, 3-level heading hierarchy, 4 weights.

Font families
Sans (system)font-sans

The quick brown fox jumps over the lazy dog

All body text, UI labels, inputs. System font stack for native feel.

Heading (Space Grotesk)font-heading

The quick brown fox jumps over the lazy dog

Display headings, branding. Tight letter-spacing, geometric terminals.

Mono (Geist Mono)font-mono

const memory = await memax.recall(query);

Code snippets, token names, technical values.

Heading hierarchy (3 levels)
H1

Settings

text-[21px] font-bold21px · 700 (bold)Memory detail title, page header (one per view)
H2

Deployment Strategy

text-[16px] font-bold16px · 700 (bold)Section header, note detail title
H3

React Server Components

text-[14px] font-semibold14px · 600 (semibold)Card title, list item title, sub-section

Rule: one H1 per view. H2 for sections within a page. H3 for cards/list items. Never skip levels.

Type scale — CSS variables
TokenSizeTailwindUsage
--text-title18pxtext-[18px]Modal title, page header
--text-input15→16pxtext-[15px] sm:text-[16px]Bar input, placeholders
--text-body14pxtext-[14px]Card title, body, AI answer
--text-secondary13pxtext-[13px]Snippet, citation, button label
--text-caption12pxtext-[12px]Category, timestamp, meta
--text-micro11pxtext-[11px]Group header, keyboard hint
--text-nano10pxtext-[10px]Citation badge, section label, DemoCard label
Type scale — live rendering
Memory title here
What did we agree on for v2?
Your deployment strategy combines blue-green with canary releases.
Copy to clipboard
core · 2h ago · 3 sources
RECENT MEMORIES
TYPE SCALE
Weight scale
400Regular

The quick brown fox jumps over the lazy dog

500Medium

The quick brown fox jumps over the lazy dog

600Semibold

The quick brown fox jumps over the lazy dog

700Bold

The quick brown fox jumps over the lazy dog

Rule: never use font-light (300) or font-black (900). Product uses 400–700 range only.

Text color hierarchy
fg-1Primary text — titles, body, input value
fg-2Secondary text — descriptions, placeholders
fg-3Tertiary text — timestamps, meta, labels
fg-4Decorative — hints, divider text, annotations

All computed from --foreground via oklch opacity. Adapts automatically to dark mode. Never use raw foreground/XX — always use text-fg-N classes.

Line height
1.0leading-none
Icons, single-line labels, badges
1.4leading-tight
Card titles, compact text
1.5leading-snug
Bar input (22px line-height on 15px)
1.65leading-[1.65]
AI answers, prose body, readable paragraphs
Composition — memory card
React Server ComponentsH3

Server components render on the server and send HTML. Client components hydrate on the client.

core·2h ago

Title: text-[14px] font-semibold text-fg-1 (H3)

Body: text-[13px] text-fg-2 leading-[1.65] line-clamp-2

Meta: text-[12px] text-fg-3 / text-fg-4

14. Surfaces

5-level elevation hierarchy + 5 Surface variants. Every container in the product uses one of these combinations.

Elevation hierarchy (5 levels)
0
0 — Page

Page canvas, scroll body. No border, no shadow.

Layout root, brain view scroll area
1
1 — Content

Content container. Subtle border (--border), no shadow.

Memory detail body (desktop), settings sections
2
2 — Elevated

Primary cards. Bar-border (12% opacity) + layered shadow.

Memory grid cards, topic cards, bar, floating panels
3
3 — Floating

Above-page overlays. Glass blur + frosted edge.

Dropdowns, popovers, command palette
4
4 — Modal

Full-screen overlay with backdrop dimming.

MemoryModal, settings dialog, confirmations

Rule: never skip elevation levels. Page → Content → Elevated → Floating → Modal.

Surface component — 5 variants (live)
DefaultFull elevation — bar-border + bar-shadow
<Surface variant="default">Memory grid, topic cards, bar
SubtleLight border, no shadow — recedes behind content
<Surface variant="subtle">Memory detail body (desktop), inline containers
FlatSame as subtle (alias) — semantic distinction for different context
<Surface variant="flat">Inline sections, nested containers
BorderlessNo border, no shadow, no rounding — full bleed
<Surface variant="borderless">Mobile detail page, fullscreen views
CleanCard background only, no border — minimal container
<Surface variant="clean">Minimal containers, collapsed sections
Bar surface
What did we agree on for v2?
h-14 · rounded-2xl · bg-card · bar-border · bar-shadow
Floating panel (dropdown / popover)

Item one

Description here

Item two (hover)

Same border/shadow as bar. Separator: border-t border-border/30. Hover: bg-surface-1.

Border radius scale
Bar16pxrounded-2xl
Card12pxrounded-xl
Component8pxrounded-lg
Small6pxrounded-md
Pill9999pxrounded-full

Rule: outer container always has larger radius than inner. Bar/modal 16px → card 12px → button 8px → nested 6px.

Glass edges (functional only)

Glass communicates layer hierarchy: “this floats above that.” Never decorative.

Frosted edge (scroll top/bottom)

backdrop-blur(20px) saturate(1.4) · mask-image dissolve

Dissolve gradient (infinite canvas)

linear-gradient(to top, var(--card), transparent) · 120px
Decision tree — which Surface?
1.
Is it a card in a grid? → default (border + shadow)
2.
Is it a detail/section body? → subtle (border only)
3.
Is it mobile or fullscreen? → borderless (no border, no rounding)
4.
Is it a minimal wrapper? → clean (bg only)
5.
Is it floating above content? → use bar-border + bar-shadow directly (not Surface)

20. Layout

Page widths, 8px spacing grid, responsive breakpoints, z-index hierarchy, and safe area insets. Every layout decision references this.

Page widths
Bar
max-w-[640px]

Global input bar. Centered, responsive width shrinks on larger screens.

w-[calc(100%-32px)] sm:w-[calc(100%-96px)] md:w-[calc(100%-128px)]
Content (brain view)
max-w-4xl (896px)

Memory grid, topic detail. Outer padding + inner max-width.

px-4 sm:px-8
Memory detail
max-w-4xl (896px)

Same max-w as list — container morphs, no new surface.

px-5 sm:px-8 md:px-10
Settings modal
880px

Centered dialog. Sidebar nav (desktop), tabs (mobile).

sidebar 220px + content px-8
Share target
max-w-sm (384px)

Single card, centered. PWA share sheet capture.

p-5
Width comparison (visual)
Share (384px)43%
Bar (640px)71%
Settings (880px)98%
Content (896px)100%
Spacing grid (4px base, 8px primary)
4gap-1
8gap-2
12gap-3
16gap-4
24gap-6
32gap-8
48gap-12
64gap-16
4pxgap-1Micro gaps (icon-to-icon, badge internal)
8pxgap-2Inline gaps (icon + text, dots)
12pxgap-3Tight element spacing (badge group)
16pxgap-4Card padding, grid gap, section gaps
24pxgap-6Section spacing within a page
32pxgap-8Section margin, page top padding
48pxgap-12Large section breaks, page bottom
64pxgap-16Page-level spacing (rarely used)
Responsive breakpoints
Mobile(default)
0px639px

Single column, pill chips, bottom bar, borderless surfaces

Tabletsm:
640px767px

2-column grid, text mode toggle, larger type

Desktopmd:
768px1023px

3+ column grid, sidebar peek, full bar width

Widelg:
1024px

Pinned sidebar, max content width, settings modal

Rule: mobile-first. Default styles = mobile. Add sm: / md: / lg: for larger screens. Never hide critical functionality behind a breakpoint.

Z-index hierarchy
z-65
MemoryModal content
z-60
MemoryModal backdrop
z-50
Bar + logo + avatar (fixed bottom)
z-10
Frosted scroll edges
z-[3]
Below-bar hints, expand area
z-[2]
Main content, memory cards
z-[1]
Background elements, decorative layers

Rule: bar is z-50, modal is z-60+. Content lives at z-[1-3]. Never use arbitrary z values — pick from this list.

Safe area insets (CSS env())
--safe-topStatus bar inset (iOS notch)
--safe-bottomHome indicator (iPhone), bar clearance
--safe-leftLandscape notch (left)
--safe-rightLandscape notch (right)
padding-bottom: calc(var(--safe-bottom) + 16px);

Bar uses safe-bottom for iPhone home indicator clearance. Always add safe area to fixed bottom elements.

Composition — page layout
max-w-4xl content
bar (z-50, fixed bottom)

z-[2]: content

z-50: bar

Content scrolls behind bar. Bar is fixed bottom center. No sidebar, no top bar. Bottom padding: safe-bottom + bar height + 16px clearance.

18. Motion Tokens

Named timing constants + easing curves. Every animation references a token — never raw durations. Spring easing is the default.

Duration tokens
INSTANT

0.1s

UI state changes — intent label swap, right slot toggle, hover feedback

opacity: 0 → 1 on hover
FAST

0.15s

Modal open/close, expand slot, view switch, dropdown appear

scale: 0.96 → 1 on mount
NORMAL

0.2s

Content dissolve, list reorder, layout shift, page transition

translateY: 6px → 0 on enter
LOADING

0.5s

Breathing dots, loading pulses, skeleton shimmer

opacity: 0.3 → 1 loop
SIGNATURE

3.5s

Placeholder cycling, ghost breathing, slow atmospheric loops

crossfade placeholder text

CSS: var(--duration-*) · JS: import { INSTANT, FAST, NORMAL, LOADING, SIGNATURE }from "@/lib/motion"

Duration comparison — interactive
0.1s
0.15s
0.2s
0.5s
3.5s
Easing curves
Spring
cubic-bezier(0.16, 1, 0.3, 1)

Default for all UI transitions. Fast start, gentle settle. Apple-like feel.

Use for: Everything unless specified otherwise

Bounce
cubic-bezier(0.34, 1.56, 0.64, 1)

Slight overshoot then settle. Playful, attention-drawing.

Use for: Toast enter, success indicator, notification badge

Rule: never use linear or ease-in-out. Spring easing is the memax feel. Set it once in Framer Motion transition or CSS transition-timing-function.

Easing comparison — interactive
Spring (default)
Bounce
Linear (never use)
ease-in-out (never use)

Red = forbidden easings. Notice how linear feels robotic and ease-in-out feels sluggish compared to spring.

Named animations (globals.css keyframes)
animate-content-ready

Skeleton → content transition. Opacity 0→1 + translateY 6px→0.

0.15sAll loading → loaded state changes globally
state-slow-breathe

Gentle opacity pulse 0.3→1. For AI processing indicators.

2.5s infinite✦ star during AI streaming, "organizing..." text
state-fast-pulse

Quick opacity pulse. For active processing feedback.

1s infiniteCategory dot during processing, inline loading
animate-fade-up

Entrance: opacity 0→1 + translateY 8px→0.

0.3sSection entrance, staggered list items
MemaxLoader

Sequential pulse dots in signature color. Brand loading.

per-dot staggerFull-page cold start, route transition
Live — breathing indicators
slow-breathe
fast-pulse
static

slow-breathe: AI streaming/processing. fast-pulse: active card processing. static: complete/idle.

Status messages (RecallingText)
memax listening
memax organizing
memax dreaming
memax connecting dots
memax thinking

Crossfade cycle during AI loading. Source: RecallingText component. verb breathes in signature color.

Motion rules
1.

Never use raw durations — always reference a token (CSS var or JS constant)

2.

Spring easing everywhere — never ease-in-out, never linear

3.

Signature color only breathes — never flashes, never blinks

4.

No animation > bad animation — if unsure, use a simple opacity fade

5.

prefers-reduced-motion — respect system setting, disable non-essential motion

27. Accessibility

WCAG contrast ratios (calculated from real tokens), focus management, reduced motion, touch targets, color blindness. Hard rules, not guidelines.

Contrast ratios — WCAG 2.1 (calculated)
TokenOpLight/bgLight/cardDark/bgAAAA LgUsage rule
fg-1
/9012.2:112.7:112.9:1PASSPASSUse for all body text, titles, headings, input values. No restrictions.
fg-2
/655.2:15.3:17.3:1PASSPASSSafe for descriptions, placeholders, secondary labels. Passes AA at all sizes.
fg-3
/402.5:12.5:13.7:1FAILFAILDECORATIVE ONLY in light mode. Timestamps, meta, category labels. Never for readable body text. Dark mode passes AA large (3.7:1).
fg-4
/201.5:11.5:11.9:1FAILFAILNON-TEXT ONLY. Hints, annotations, divider text, decorative labels. Never for any content a user needs to read.

WCAG 2.1 AA requirements:

Normal text (<18px): minimum 4.5:1 contrast ratio

Large text (≥18px bold or ≥24px): minimum 3.0:1 contrast ratio

Non-text (icons, borders): minimum 3.0:1 contrast ratio

Signature color (Dream Violet) — contrast
Light bg:4.8:1AA large PASS
Dark bg:3.3:1AA large PASS

Signature passes AA large text (3:1) in both modes. Safe for ✦ indicators (typically 12-20px) and button fills (white text on signature bg). Not safe for small body text in light mode.

Token → text size rules (LLM reference)
fg-1

Any size, any weight. No restrictions. (12.2:1+)

fg-2

Any size, any weight. Safe everywhere. (5.2:1+)

fg-3

Minimum 12px. Use for timestamps, meta, labels — never for content users must read. (2.5:1 light, 3.7:1 dark)

fg-4

Decorative only. Annotations, DemoCard labels, divider dots. Never for readable text. (1.5:1+)

Known trade-off: fg-3 fails WCAG AA for normal text in light mode. This is intentional — fg-3 is for supplementary metadata (timestamps, category labels) where the information is also conveyed by position, grouping, or icon. If the text must be readable standalone, use fg-2.

Focus ring specification
Button (all variants)
focus-visible:ring-3 focus-visible:ring-ring/50 focus-visible:border-ring3px ring at 50% opacity of --ring. Border also changes to --ring.
Button (destructive)
focus-visible:border-destructive/40 focus-visible:ring-destructive/20Red-tinted ring for destructive actions.
Input fields
focus:border-ring focus:ring-2 focus:ring-ring/502px ring (smaller than button). Border transitions to --ring.
Toggle switch
Browser default (no custom ring)Relies on native focus indicator. TODO: add visible ring.
Links / text buttons
focus-visible:ring-2 focus-visible:ring-ring/50 focus-visible:roundedSubtle 2px ring with rounded corners.

Focus rules:

1. Always use focus-visible, never focus — keyboard users only, not mouse clicks

2. Ring color is --ring at 50% opacity — visible but not aggressive

3. Tab order follows visual layout. No custom tabIndex unless absolutely necessary

4. All interactive elements must be reachable via Tab key

Live — focus ring demo (press Tab)

Tab through to see focus rings. Ring is always 3px (buttons) or 2px (inputs) with --ring at 50%.

Reduced motion — prefers-reduced-motion

When prefers-reduced-motion: reduce is set, these animations are disabled:

animate-content-ready → instant opacity (no transform)

animate-fade-up → removed

state-fast-pulse → static (no pulse)

state-slow-breathe → static (no breathe)

Framer Motion respects useReducedMotion() automatically. CSS-only animations use the media query in globals.css (line 1016).

What stays:

Color transitions (opacity, background) — these are non-motion

MemaxLoader dots — reduced to static display (no sequential pulse)

Placeholder text crossfade — kept but instant (no blur transition)

Touch targets — minimum sizes
44
44×44px

Primary actions: send button, mode pills, nav items, toggle switches

36
36×36px

Secondary actions: icon buttons (icon-lg), close buttons

32
32×32px

Tertiary: icon buttons (default), copy buttons, tag remove

24
24×24px

Minimum: icon-xs buttons. Only for non-critical, supplementary actions

WCAG 2.5.8: minimum 24×24px target. Apple HIG: 44×44pt for primary actions. Memax follows Apple for primary, WCAG for minimum.

Color blindness — rules
1.

Category dots use 13 distinct hues — not distinguishable by color alone

2.

Every dot is accompanied by a text label (category name) — color is supplementary

3.

Red (destructive) is always paired with text or icon (Trash2), never color-only

4.

Signature (violet) vs error (red) — sufficiently different hue for deuteranopia

5.

Never convey meaning through color alone — always pair with text, icon, or shape

Keyboard navigation map
TabMove focus to next interactive element
Shift+TabMove focus to previous element
EnterActivate button, submit form, open memory
EscapeClose modal, dismiss notification, clear bar
↑ / ↓Navigate memory rows, dropdown items
/Focus the bar (brain view)

15. Palette Explorer

Interactive theme preview. Switch presets to compare text hierarchy, surfaces, and accents live.

Purple-blue inspired by dreams. Distinctive, creative, memax's signature feature.

Text hierarchy
Primary/90

Memory card title

Secondary/52

Last recalled 3 hours ago from CLI

Tertiary/40

core / api-design / 2024-03-15

Muted/25

Content hash: 8f3a...

Readability test on card surface

Secondary text should be clearly readable without straining. If you squint to read this, the opacity is too low.

Tertiary text recedes but stays legible — timestamps, categories, metadata.

Muted text: placeholders, disabled labels, hashes.

LevelSafe NeutralWarm ApricotCool SlateEarth CopperDream Violet
Primary0.90.90.90.920.9
Secondary0.50.50.520.550.52
Tertiary0.380.40.40.420.4
Muted0.250.250.250.280.25
Signature color comparison
Safe Neutraloklch(0.50 0 0)
Warm Apricotoklch(0.72 0.14 60)
Cool Slateoklch(0.65 0.10 240)
Earth Copperoklch(0.62 0.14 45)
Dream Violetoklch(0.62 0.16 290)
Gray ramp comparison

Safe Neutral (pure achromatic)

bg
card
muted
border
ring
input
muted-fg
secondary
lt-border
lt-bg

Dream Violet tint

bg
card
muted
border
ring
input
muted-fg
secondary
lt-border
lt-bg
Full card preview
API Design Patterns

REST endpoints should use plural nouns. Pagination via cursor, not offset.

core / api-design3h ago
search your memory...
Architecture Decision RecordsPRO

We chose River over SQS because Postgres-backed queues simplify our infra. Trade-off: no cross-region fan-out, but we don't need it at current scale.

decisions / infrastructurerecalled 12 timessha:4f2c...
Functional accent palette
EmberCTA / primary actions
oklch(0.65 0.18 35)
HoneycombHighlights / hover / search match
oklch(0.82 0.16 85)
SageSuccess / saved / connected
oklch(0.72 0.10 155)
DuskLinks / info accents
oklch(0.55 0.08 260)
PlumPremium / Pro indicators
oklch(0.52 0.14 310)
ClaySecondary / tertiary UI
oklch(0.58 0.06 50)
SignalError / destructive / critical
oklch(0.62 0.22 25)
Accents in context
PRO● Saved● Error
Regular text with a Dusk link color and Honeycomb highlight

2026 trend: warm-tinted grays (Linear, Notion) + bold single accent (Superhuman 0.18, Vercel 0.21). Category dots unchanged — data layer, not UI chrome.

19. Controls

Complete interactive control gallery. All variants rendered from production components (ui/button.tsx, ui/badge.tsx, ui/tag.tsx).

Button — variants

<Button variant="default|outline|secondary|ghost|destructive|link">

Source: ui/button.tsx — CVA variants, @base-ui/react primitive

Button — sizes
xsh-6
smh-7
defaulth-8
lgh-9
Button — with icons

Use data-icon="inline-start|inline-end" for padding adjustment

Button — icon-only sizes
icon-xs24px
icon-sm28px
icon32px
icon-lg36px
Badge — variants
DefaultSecondaryOutlineDestructiveGhost
coreprocess3 sourcesErrorPro

<Badge variant="default|secondary|outline|destructive|ghost">
Source: ui/badge.tsx — h-5, rounded-4xl, text-xs

Tag — removable pills
reactdeploymentremovablehover to see ×

<Tag onRemove={fn}>label</Tag>
Source: ui/tag.tsx — bg-surface-1, border-border, rounded-lg, × on hover

Send button — bar-specific control
Push
Recall
Loading
Disabled

h-8 w-8 rounded-lg. Push: foreground fill. Recall: signature fill. Source: bar-right-portal.tsx

Toggle switch

Off: transparent track, foreground/15 border. On: signature fill, white knob.
Track: w-10 h-6 rounded-full. Knob: w-4.5 h-4.5 rounded-full.

Toggle — async (optimistic + pending)

Optimistic: switch moves immediately. Pending: border pulses until server confirms (600ms simulated).

Input field

h-8, rounded-lg, border-border, focus: border-ring + ring-2 ring-ring/50

Pill chips — mode toggle
remember·recall
rememberrecall

Desktop: text "remember · recall" (dot separator). Mobile: pill chips with 44px min touch target. Source: layout.tsx mode toggle

Composition — settings row
Hub name

Visible to all team members

Danger zone

This action cannot be undone

Pattern: label+description left, action button right. Separator: border-t border-border/20.

17. Visual Vocabulary

Two symbols only: ● dot (content) and ✦ star (memax intelligence). Behavior modifiers signal state.

● Dot — content indicator
Static — complete/resting
Fast pulse 0.8s — processing
Slow breathe 2.5s — idle
Fade out — deleting
Flash — error occurred
✦ Star — memax intelligence
Static — complete/at rest
Fast pulse 0.8s — actively working
Slow breathe 2.5s — waiting

Star uses signature color: oklch(0.62 0.16 290)

Size scale — optical balance

Star font-size ≈ 1.5× dot diameter for equal visual weight (star glyphs have more whitespace than filled circles).

xs
4 / 8pxdense lists
sm
6 / 10pxcards (default)
md
8 / 12pxsection headers
lg
12 / 20pxpage loading

16. State Machine

Content states + activity indicators. No ambiguous states.

16a. Content state transitions
  LOADING ──→ LOADED ──→ UPDATING ──→ LOADED
    │            │                        │
    │            ├──→ DELETING ──→ (removed)
    │            │
    ├──→ EMPTY   ├──→ ERROR
    │            │         │
    └──→ ERROR   └─────────┘ (retry → LOADING)

  Separate track:
  LOADED ──→ PROCESSING ──→ LOADED (auto-poll)
Loading
Empty
Loaded
Updating
Deleting
Error
Processing
16b. Activity Status Dots

Reusable liveness indicator for agents, services, connections. Derived from timestamps (last_used, last_seen) — no polling, no websocket. Green pulses to draw attention; others are static.

sm
active
idle
inactive
error
md
active
idle
inactive
error
lg
active
idle
inactive
error

Usage

>_
Claude Code2m ago3 keys
Embedding servicequeued
MCP connectiontimeout

Activity status rules

active— last_used <24h. Green + animate-ping pulse.

idle — last_used 1-7d. Amber, static.

inactive— >7d or never. Muted fg-4, static.

error — connection failure or expired key. Destructive red, static.

Production: lib/agents.ts (StatusDot in agent-configs-section.tsx). Extend for service health, MCP status, sync state.

8. Loading States

Shape before content. Signature color only when memax is actively working.

Full page — cold start

Loading your memory...

MemaxLoader (signature-colored sequential pulse dots) is the brand. Centered on background, not card. Text at /40. Used on brain view during initial load.

Full page — route transition

Brief transition. Compact loader, no text — user already knows where they're going.

AI streaming — breathing ✦ + summary callout
Your deployment strategy combines blue-green deployment with canary releases [1]. For risk mitigation [2], you use gradual rollouts...
Complete answer with static star — streaming done.

AI answer uses summary callout pattern (bg-surface-1 rounded-xl). Entry: animate-content-ready. ✦ breathes (state-slow-breathe) while streaming, static when complete. Text at /75.

Content area — skeleton grid

Skeleton mirrors loaded card: dot+title, body, meta. Shimmer uses foreground opacity, not gray — adapts to dark mode.

Recall loading — send button spinner + AI cycling text

Recall loading: send button shows spinner (no notification banner). AI synthesis loading: ✦ breathing + RecallingText variant="ai" crossfade below results ("memax is thinking" → "reading your memories" → "connecting the dots"...).

memax is thinking
Transition — skeleton → content (animate-content-ready)

0.15s ease-out, opacity 0→1 + translateY 6px→0. Applied globally to all loading→loaded transitions. Click to replay.

Inline — card processing indicator
Docker multi-stage builds

Use multi-stage builds to keep production images small. Separate build dependencies from runtime...

process·organizing...

Card appears immediately with content. ✦ replaces category dot during processing. "organizing..." breathes in signature color.

9. Empty States

Three tiers: first-time onboarding, filtered no-results, and transient empty.

First-time

No memories yet

Type anything and press Enter to remember

Remember something →
Filtered

No memories in code

Transient

No reviews pending

Recall zero-results

No matching memories found.

Try different words or rephrase your question.

i18n: recall.noResults, recall.noResultsHint. Shown inside bar expand slot when recall returns 0 results. No icon — text only.

i18n: empty.firstTime.title, empty.firstTime.subtitle, empty.firstTime.cta, empty.filtered.title, empty.filtered.cta, empty.transient, recall.noResults, recall.noResultsHint

28. Async Action Pattern

Universal mutation lifecycle: Idle → Pending → Success/Error → Idle. MutationCache global handlers with meta-driven feedback. Zero per-callsite wiring.

28a · State Machine
Idle
Pending
Success
Error
→ idle
Ready
28b · Toast Styles
Success
3 memories forgotten
Error
Couldn't forget memories
Info / Pending
Remembering...
28c · Pattern Reference (LLM)
Architecture

MutationCache on QueryClient handles ALL mutation feedback globally.

meta.successMessage — static string or (data, vars) => string for dynamic messages.

meta.errorMessage — same signature. Shown for 5s with dismiss.

meta.skipGlobalToast — for mutations with custom UX (push flow with undo).

Bridge: module-level callback ref (mutation-toast.ts) wired by BarProvider on mount.

Rules for Adding New Mutations
  1. Add meta: { errorMessage: t.toast.* } to every mutation — even if optimistic rollback handles the UI.
  2. Add successMessage only for irreversible or batch actions (disconnect, batch delete).
  3. Use skipGlobalToast: true only when the mutation has its own undo-capable feedback.
  4. Callsite callbacks are for UI side-effects only (selection.exit(), navigation) — never for toasts.
  5. All messages go through i18n (t.*). Dynamic messages use interpolate().
  6. useBarToast() is ONLY for non-mutation feedback (clipboard copy, DnD drop). Never use it inside mutation callbacks — MutationCache handles that.
28d · Mutation Inventory
HookSuccessError
useBatchDeletedynamic (count)t.batch.forgetFailed
useBatchMoveToTopicdynamic (count)t.batch.moveFailed
useBatchMoveToHubdynamic (count)t.batch.moveFailed
useCreateMemorysilentcustom
useUpdateMemorysilentt.toast.updateFailed
useDeleteMemorysilentt.toast.deleteFailed
useShareMemoryt.toast.sharedt.toast.shareFailed
useDisconnectAgentt.toast.disconnectedt.toast.disconnectFailed
useUpdateAgentsilentt.toast.updateFailed
useDeleteAgentConfigsilentt.toast.deleteFailed
useRevokeApiKeysilentt.toast.revokeFailed
useCreateTopicsilentt.toast.topicFailed
useUpdateTopicsilentt.toast.topicFailed
useDeleteTopicsilentt.toast.topicFailed
useAddMemoryToTopicsilentt.toast.topicFailed
useRemoveMemoryFromTopicsilentt.toast.topicFailed
useResolveReviewsilentt.toast.reviewFailed
useUpdateSettingssilentt.toast.settingsFailed
useDreamTriggersilentt.toast.organizeFailed

26. Composition Recipes

Full-page assembly from tokens → components → layout. Copy the structure, swap the content. Every class is annotated with its source section.

Recipe — Brain View (memory grid)
Recent
React Server Componentscore · 2h

Server components render on the server...

Deployment strategyprocess · 5h

Blue-green with canary releases...

Auth middleware decisiondecisions · 1d

Moving to JWT with refresh rotation...

Topics
Deployment
12 memories
Architecture
8 memories
mWhat did we agree on...

max-w-4xl · px-5 sm:px-8

pb-36 md:pb-32 (bar clearance)

bar: z-50, fixed bottom center

Container: max-w-4xl mx-auto px-5 sm:px-8 pb-36 md:pb-32

Group header: text-[10px] text-fg-3 uppercase tracking-wider font-semibold

Memory row: px-4 py-2.5 border-t border-border/30 hover:bg-surface-1

Topic card: Surface variant="default" p-3

Bar: fixed bottom center, z-50, rounded-2xl, bar-border + bar-shadow

Recipe — Memory Detail (borderless)

React Server Components

Forget
>_Claude Codecaptured·memax·2d ago·recalled 47×
memax summary

Server components render on the server and send HTML. Client components hydrate on the client. The boundary is the "use client" directive.

Original content·342 words
reactarchitecture
core·private

borderless — no Surface card

provenance strip: agent + captured + age + recalled

summary: text-fg-1 hero, ✦ signature

raw content: collapsed disclosure, text-fg-2

dissolve into --background

Borderless — no Surface card. All on --background.

Provenance: agent icon + name + captured + project + age + recalled N×

Summary: text-fg-1 hero, ✦ in signature. Raw content: collapsed disclosure, text-fg-2.

Sections: border-t border-border/20 + mt-5 pt-5. All content pl-8.

Dissolve: linear-gradient(to top, var(--background), transparent)

Recipe — Settings Dialog
General
Integrations
Intelligence
Advanced

General

Display name

Visible to team members

Theme

System, Light, or Dark

System
Memory Dreams

Nightly consolidation

z-60: backdrop rgba(0,0,0,0.15)

z-65: modal 880px centered

sidebar: 220px, border-r border-border/30

rows: divide-y divide-border/20

Modal: 880px centered, z-65, rounded-2xl, bar-border + bar-shadow

Backdrop: z-60, rgba(0,0,0,0.15)

Sidebar: 220px, border-r border-border/30

Active tab: bg-surface-2 text-fg-1 font-medium

Rows: divide-y divide-border/20, py-3

Copy-paste markup — for LLM agents and developers

Structured code blocks for the most common patterns. Copy directly into new components.

Memory RowBrain view grid, topic detail, search results
<div className="w-full px-4 py-2.5 hover:bg-surface-1 transition-colors border-t border-border/30">
  <div className="flex items-center gap-2">
    <span className="h-1.5 w-1.5 rounded-full" style={{ background: dotColor }} />
    <span className="text-[14px] font-medium text-foreground truncate flex-1">{title}</span>
    <span className="text-[13px] text-fg-3 tabular-nums">{meta}</span>
  </div>
  <p className="text-[13px] text-fg-3 truncate mt-0.5 pl-5">{summary}</p>
</div>
AI Distillation (memory detail hero)Memory detail — summary as primary content, on --background
<div>
  <div className="flex items-center gap-1.5 mb-3">
    <span className="text-[12px]" style={{ color: "var(--signature)" }}>✦</span>
    <span className="text-[13px] text-fg-3">memax summary</span>
  </div>
  <div className="text-[16px] text-fg-1 leading-[1.65]">{summary}</div>
</div>
Settings RowSettings dialog, hub management
<div className="flex items-center justify-between py-3">
  <div>
    <span className="text-[14px] text-fg-1">{label}</span>
    <p className="text-[12px] text-fg-3">{description}</p>
  </div>
  <Button variant="outline" size="sm">{action}</Button>
</div>
Page ShellAny new route under /(app)/
<div className="pb-36 md:pb-32 animate-content-ready" style={{ paddingTop: CONTENT_TOP }}>
  <div className="mx-auto max-w-4xl px-5 sm:px-8">
    {/* Page content */}
  </div>
</div>
Group HeaderSection label above memory rows or card grids
<span className="text-[10px] text-fg-3 uppercase tracking-wider font-semibold">
  {groupLabel}
</span>
Empty StateNo results, empty topic, first-run
<div className="flex flex-col items-center justify-center text-center" style={{ minHeight: CENTERED_HEIGHT }}>
  <p className="text-[16px] text-fg-2 mb-2">{message}</p>
  <p className="text-[13px] text-fg-3">{hint}</p>
</div>
Token cheat sheet — quick lookup

Page layout

width: max-w-4xl (896px)

padding: px-5 sm:px-8

bottom: pb-36 md:pb-32

top: CONTENT_TOP (80px)

entrance: animate-content-ready

Surfaces

grid card: Surface variant="default"

detail: borderless (no Surface)

section sep: border-t border-border/20

row hover: hover:bg-surface-1

row divider: border-t border-border/30

Typography

H1: text-[21px] font-bold

H2: text-[16px] font-bold

H3: text-[14px] font-semibold

body: text-[14px] text-fg-1

meta: text-[12px] text-fg-3

Motion

easing: var(--ease-spring)

fast: 0.15s (modal, hover)

normal: 0.2s (content, layout)

enter: animate-content-ready

ai: state-slow-breathe

1. Knowledge Space

Unified MemoryRow component used across all surfaces. One component, surface-driven presets. Attribution tiers: agent (Bot) → team (avatar) → personal (dot). Kitchen defines the spec, production implements it.

1a. Row anatomy — universal 2-line structure

Every memory row: title (bold) + optional summary (muted). No tags at row level. Indicator + meta area adapt by surface/attribution. Hub label in right meta for team memories. Edge-to-edge within card (px-4), no rounded rows, flat dividers.

Blue-green deployment strategy
backend-team2d

Zero-downtime deploys using blue-green with Fly.io machines...

Line 1: [Indicator] Title [Meta: hub, age, copy]
Line 2: Summary (optional, pl-5 indent). No tags at row level.
1a-exp. Row without category — 3 options

If category is fully removed, what anchors the left side? Comparing: title-only, content-type icon, and tags-inline. Agent/team attribution tiers are unaffected (they already don't use category).

A. Title only — no indicator

Blue-green deployment strategy2d

Zero-downtime deploys using blue-green with Fly.io machines...

fly.iozero-downtimeinfra
Staging deploy process3d

Push to staging branch triggers auto-deploy...

B. Content-type icon — visual anchor, no label

Blue-green deployment strategy2d

Zero-downtime deploys using blue-green with Fly.io machines...

Staging deploy process3d

Push to staging branch triggers auto-deploy...

Architecture whiteboard photo1w
Fly.io multi-region docs5d

Neutral dot for text, FileText for PDF, ImageIcon for image, LinkIcon for link. All foreground/20 (no category color).

C. First tag as context label — replaces subcategory

fly.io·Blue-green deployment strategy2d

Zero-downtime deploys using blue-green with Fly.io machines...

staging·Staging deploy process3d

Uses first tag as context label. More specific than category but varies wildly. Only works if tags are consistently short.

1b. Attribution tiers — who/what pushed this?

The indicator slot answers “who pushed this?” — not “which category.” Three tiers in priority order. Category dots remain as fallback for personal default only.

Tier 1 — Agent auto-capture
claude-codeSession: refactored ingest pipeline
backend-team8h

Moved chunking from handler to dedicated worker, added retry logic...

Tier 2 — Team human push
D
DerekAPI auth flow
backend-team2h

OAuth2 refresh token rotation with 30-day expiry...

Tier 2b — Team human via agent
cursorReranker cost analysis
backend-team5h

Cohere rerank v3 at $1/1000 queries, 50ms p95...

Tier 3 — Personal (fallback to content-type dot)
Blue-green deployment strategy
5×cli2d

Zero-downtime deploys using blue-green with Fly.io machines...

1b-hub. Hub attribution — compact vs clean

Two layout options for team hub memories in the personal “all” view. Compact: inline context, hub in right meta. Clean: attribution line above, title always left-aligned, verbs describe the action.

Compact — inline context, hub in meta

Blue-green deployment strategy
5×cli2d

Zero-downtime deploys using blue-green with Fly.io machines...

D
DerekAPI auth flow
backend-team2h

OAuth2 refresh token rotation with 30-day expiry...

claude-codeSession: refactored ingest pipeline
backend-team8h

Moved chunking from handler to dedicated worker, added retry logic...

A
AlexFigma token export workflow
design-team1d

Dense, scannnable. Hub in right meta (11px, /25). Titles slightly misaligned due to varying context label width.

Clean — attribution above, verbs, titles aligned

Blue-green deployment strategy2d
D
Derek pushed· backend-team2h
API auth flow
claude-code captured· backend-team8h
Session: refactored ingest pipeline
A
Alex pushed· design-team1d
Figma token export workflow

Titles always left-aligned. Verbs: pushed (human), captured (agent). Attribution line only for team memories. Personal rows stay single-line. Taller rows but clearer hierarchy.

1c. Content type indicators — personal tier only

When no agent/team attribution, the indicator shows content type. Color comes from category (may be deprecated — dot color is the only remaining category signal).

Blue-green deployment strategy
2d

Zero-downtime deploys using blue-green with Fly.io machines...

Staging deploy process
3d

Push to staging branch triggers auto-deploy...

Architecture whiteboard photo
1w

System diagram from Monday standup...

Fly.io multi-region docs
5d

Official guide for multi-region Postgres with read replicas...

Text → colored dot · PDF → FileText icon · Image → ImageIcon · Link → LinkIcon. All colored by category dot color.

1d. Surface presets — same memory, 5 contexts

Same memory rendered on each surface. Surface controls which lines appear, which meta is shown, and whether copy is available.

Recent — full meta + copy

Blue-green deployment strategy
5×cli2d

Zero-downtime deploys using blue-green with Fly.io machines...

Inbox — minimal, just title + age

Blue-green deployment strategy
2d

Topic — summary focus, no source

Blue-green deployment strategy
2d

Zero-downtime deploys using blue-green with Fly.io machines...

List — source + count + age

Blue-green deployment strategy
5×cli2d

Zero-downtime deploys using blue-green with Fly.io machines...

Recall — summary focus, no source/count

Blue-green deployment strategy
2d

Zero-downtime deploys using blue-green with Fly.io machines...

1e. Processing state — ✦ organizing...

Universal across all surfaces. ✦ breathes with signature color. No summary, no tags, no meta — just title + status.

CleanShot 2026-04-08organizing...
Blue-green deployment strategy
5×cli2d

Zero-downtime deploys using blue-green with Fly.io machines...

1f. Knowledge hub — Recent + Topics + Inbox

Full layout: page header → Recent section (Clock, dropdown time filter, “Copy N for AI”) → topic cards grid → inbox (Inbox icon, count). Gap-3 consistent spacing.

Your Knowledge

147 memories · 6 topics

Recent
CleanShot 2026-04-08organizing...
Blue-green deployment strategy
5×cli2d

Zero-downtime deploys using blue-green with Fly.io machines...

Staging deploy process
2×web3d

Push to staging branch triggers auto-deploy...

Inbox
3

Will be organized in the next dream cycle

Random debugging note
6h
Meeting with Alex re: pricing
1d
CLI flag idea for --export
2d
1f-team. Recent section — team hub attribution

In team hub, rows show WHO pushed WHAT. Same MemoryRow component, same surface="recent" — attribution tier auto-selects based on memory data.

Recent
D
DerekAPI auth flow
backend-team2h

OAuth2 refresh token rotation with 30-day expiry...

cursorReranker cost analysis
backend-team5h

Cohere rerank v3 at $1/1000 queries, 50ms p95...

claude-codeSession: refactored ingest pipeline
backend-team8h

Moved chunking from handler to dedicated worker, added retry logic...

1f-inbox. Inbox section — 3 states

Inbox behavior differs by plan. Free users wait for nightly dream cycle. Pro users can trigger organization immediately. During organization, ✦ breathes and rows show progress.

Free — wait for dream cycle

Inbox
3

Will be organized in the next dream cycle

Random debugging note
6h
Meeting with Alex re: pricing
1d

Pro — organize now

Inbox
3

3 memories waiting — organize now or let the dream cycle handle it

Random debugging note
6h
Meeting with Alex re: pricing
1d
CLI flag idea for --export
2d

Organizing — dream triggered

Inbox
organizing 3 memories...
Random debugging note
6h
Meeting with Alex re: pricing
1d
CLI flag idea for --export
2d
1g. Topic detail — description + subtopics + ungrouped

Inside a topic. Breadcrumb → header with AI description → subtopic sections → “Other” section for ungrouped memories. No category tabs (category deprecated from UI). Rows use surface="topic": summary visible, edge-to-edge (px-4, no wrapper padding).

Your KnowledgeDeployment

Deployment

23 memories · 3 subtopics

Blue-green deploys, rollback procedures, staging automation, and CI/CD pipeline configuration for Fly.io.

Staging
8
Blue-green deployment strategy
2d

Zero-downtime deploys using blue-green with Fly.io machines...

Staging deploy process
3d

Push to staging branch triggers auto-deploy...

Production
11
Fly.io multi-region docs
5d

Official guide for multi-region Postgres with read replicas...

Architecture whiteboard photo
1w

System diagram from Monday standup...

Other
4
Fly.io multi-region notes
3d
Deploy checklist draft
5d
1g-flat. Topic detail — leaf topic with description

Leaf topic (no subtopics). Description shown under header. Memories in a single flat card. No category tabs.

Your KnowledgeGo Patterns

Go Patterns

31 memories

Error handling conventions, context propagation rules, interface design principles, and goroutine lifecycle patterns.

Error handling conventions
2d

Zero-downtime deploys using blue-green with Fly.io machines...

Context propagation rules
3d

Push to staging branch triggers auto-deploy...

Interface design principles
5d

Official guide for multi-region Postgres with read replicas...

Goroutine lifecycle patterns
1w

System diagram from Monday standup...

1h. Topic card states — 4 variants

Cards show AI description for leaf topics, subtopic names for parents. No category dots. Description comes from dream engine. h-full + flex-col pins age to bottom for consistent card height.

Leaf + description

Parent + subtopics

Pinned leaf

Empty (new)

1h-next. Topic cards — memax identity, not Notion

Cards are the right container. Problem: current cards look generic. Fix: category dot DNA, AI description always visible, ✦ for dream signal, content preview for scent. Three options below.

A. Content-dense — description + memory preview + category dots

Deployment

Blue-green deploys, rollback procedures, staging automation

Fly.io machine-based blue-green with health checks
23 memories· 3 subtopics
Go Patterns

Error handling, context propagation, interface design

Table-driven tests with testcontainers setup
31 memories
Frontend

React Server Components, Tailwind, Radix primitives

TanStack Query infinite scroll with sentinel observer
22 memories· 2 subtopics

B. Compact — dots lead, description, sub-topics as · text

Deployment23

Blue-green deploys, rollback procedures

Staging · Production · Rollback

Authentication18

OAuth2 refresh flow, token rotation

Go Patterns31

Error handling, context propagation

Database15

Connection pooling, migration strategy

Frontend22

RSC, Tailwind, Radix primitives

Components · Styling

Team Docs9

Onboarding, code review guide

C. Dream accent — left-edge gradient signals AI-organized

Deployment23 · 3

Blue-green deploys, rollback procedures

Go Patterns31

Error handling, context propagation

Frontend22 · 2

RSC, Tailwind, Radix primitives

memax identity signals:

• Category dots = memax's visual DNA (not emoji)
• ✦ + dream-purple = AI organized this, not the user
• Memory preview = content scent (what's IN the topic)
• Description = dream engine output
• No timestamps — recent activity via ✦ preview

1i. Empty states — 3 variants

Pre-dream (waiting)

Topics appear after your first dream

memax will organize your memories by subject during the nightly dream cycle.

Inbox clean

Your memory is clean

Dreams disabled

Dreams are turned off

Enable dreams to organize your knowledge.

Unified MemoryRow: One component across all surfaces. surface prop controls which lines/meta appear. Attribution tier auto-selects from memory data (sourceAgent → authorName → content type dot).

Category deprecation: Subcategory labels removed from rows and cards. Category dots remain only as indicator color fallback for personal tier. Topics + tags provide better navigation. Category tabs removed from topic detail.

Topic cards: Leaf topics show AI description (from dream engine). Parent topics show subtopic names with chevrons. No category dots. h-full + flex-col pins age to bottom for consistent grid height.

Topic detail:Description under header (from dream engine). Subtopic groups + “Other” section for ungrouped memories. No category tabs. Edge-to-edge rows (px-4, no px-1.5 wrapper).

Hub attribution:Hub name lives in the RIGHT meta area (text-[11px] foreground/25) so titles stay aligned. Only in personal “all” view. Hidden when switched to a specific hub. Personal memories never show hub label. Recall results should also show hub name for cross-hub results.

Rows: Edge-to-edge within card (px-4). No rounded-lg. Flat dividers (border-t border-border/30). hover:bg-surface-1.

Copy:Per-row copy (markdown) on Recent surface only. Section-level “Copy N for AI” (context block format) on section headers + topic header.

2. Memory Detail & Recall

Borderless reading surface. No card wrapping content — like Notion, Linear, Bear. Title → provenance → AI summary → collapsed raw content → meta footer → topic siblings. Whitespace and faint lines create structure.

2a. Agent-captured, with AI summary (primary case)
React Server Components Architecture
Forget
Claude Codecaptured·memax·ARCHITECTURE.md·2d ago·recalled 47×
🏗️Architecture
memax summary

React Server Components render on the server and send HTML to the client. Client Components hydrate and become interactive. The boundary is the "use client" directive.

This enables zero-JS for static content while maintaining interactivity where needed. Data fetching happens at the component level with async/await.

Server Components are a new kind of Component that renders ahead of time, before bundling, in an environment separate from your client app or SSR server...

[Full raw content here. text-fg-2 = secondary to the distillation above.]

reactarchitectureserver-components
core·private
Also in Architecture
Deployment strategy — blue-green with canary5h
Auth middleware decision — JWT with refresh rotation1d
Database migration patterns3d

Entirely on --background. No Surface card. No border. No rounded container.

Sections separated by border-t border-border/20 + mt-5 pt-5 (whitespace + faint line)

All content pl-8 (aligned past back chevron)

Summary: text-fg-1 hero. Raw content: text-fg-2 collapsed. Tags/category: bottom.

2b. Web-captured, no summary (short memory)
Quick note about lunch meeting
Forget
you, web·3h ago

Met with Sarah about the Q3 roadmap. Key takeaways: focus on performance first, then features. Ship the caching layer before the new dashboard.

meetings
meetings·private

No summary → content at text-fg-1 directly. No ✦, no disclosure. No topic → no siblings. recalled 0× → hidden. Cleanest possible page.

2c. Processing state (just captured)
Docker multi-stage builds
Cursorcaptured·just now

Still remembering...

memax is organizing this memory

Processing: ✦ slow-breathe centered on --background. Provenance visible. No Surface card needed.

2c-ii. Loading skeleton (borderless)

Skeleton mirrors the borderless layout exactly: back button area → provenance line → content lines → footer tags. All on --background. Uses bg-foreground/[0.07] + animate-pulse with staggered delays. Transitions to loaded via animate-content-ready.

2c-iii. Error state

Couldn't load this memory

Check your connection and try again

Error: back button visible (escape route). Centered message + retry on --background. Red dot (destructive), text-fg-2 message, text-fg-3 hint, ghost retry button.

2c-iv. Loading → loaded transition

Skeleton → content uses animate-content-ready on the content wrapper. 0.15s opacity 0→1 + translateY 6px→0.

// Pattern:

{isLoading ? (

<DetailSkeleton />

) : (

<div className="animate-content-ready">

// loaded content

</div>

)}

MANDATORY for every loading→loaded swap. No pop-in without animation. Skeleton shapes must match loaded layout exactly.

2c-v. Sticky header (appears on scroll)
React Server Components Architecture

MemoryStickyHeader component. Fixed z-40, fades in on scroll via IntersectionObserver. mask-image dissolve at bottom. Shows recall count when ≥10 (activity signal in compact form). Extracted as reusable component.

2d. Forget flow — header morph

Default

Forget

Confirming

ForgetKeep

Forget left (destructive, requires movement), Keep right (safe, cursor already there). Navigation cancels.

2e. Mobile layout
React Server Components
Claude Codecaptured·memax·2d ago·recalled 47×
🏗️Architecture
memax summary

Server Components render on the server. Client Components hydrate on the client. The boundary is "use client".

Server Components are a new kind of Component...

reactarchitecture
core·private

Mobile: identical design, not "narrower desktop." Back above title. No pl-8 (no back button inline). Provenance wraps. Same borderless surface as desktop now.

2f. Activity signal — recall count scaling
Claude Codecaptured·2d ago·recalled 3×
Claude Codecaptured·1w ago·recalled 23×
Claude Codecaptured·1mo ago·recalled 127×

0=hidden, 1-9=fg-3, 10-49=fg-2 medium, 50+=fg-1 medium. Typographic weight only, no color.

Design rules — memory detail
1.

Borderless. No Surface card. Entire page is --background. Whitespace + faint border-border/20 lines separate sections. Same on desktop and mobile.

2.

Provenance first. After title: WHO captured, FROM WHERE, how often recalled. This is memax, not a note app.

3.

Summary = hero. AI distillation gets text-fg-1. Raw content collapses at text-fg-2.

4.

No summary → no split. Content renders directly. No ✦, no disclosure. Simplest case.

5.

Classification at bottom. Category + tags + boundary in footer. Top = provenance. Middle = content. Bottom = organization.

6.

Not a dead end. Topic pill → /topics/[id]. Siblings show 2-3 neighbors. Tags filterable.

3. Forget Experience

Container morphs from neutral to glassmorphism destructive tint. No modal — the surface transforms in place. Three states: normal, forgetting, forgotten.

Note header states

Normal

Normal note header

Forgetting

Forgetting…

Forgotten

This memory has been forgottenUndo
Full card morph preview

Card — Normal

React Server Components render on the server and stream HTML to the client.

3 days ago

Card — Forgetting

React Server Components render on the server and stream HTML to the client.

Are you sure?

Card — Forgotten

React Server Components render on the server and stream HTML to the client.

Memory forgotten

25. Batch Operations

Dot → check morph + glass toolbar. Entry via “Select” in section header trailing slot. Every action is end-to-end.

25a. Entry — where batch starts on each surface

Each section header has a trailing slot (right side, after spacer). “Select” lives there as subtle text. Tapping it enters selection mode — dots morph to rings, toolbar appears. “Done” exits. Same pattern on every surface.

RecentPast 24h
… memory rows …
Unassigned12
… inbox rows …
🚀Deployment23
… topic rows …

Alternative entries: long-press (mobile, 500ms), shift+click (desktop range select). Both auto-enter selection mode.

25b. Dot → Check Morph — same container, 3 states

The h-3 w-3 indicator container morphs with spring easing. No checkbox slides in. The dot IS the selection affordance.

Default
Ring
Check
25c. Full Flow — tap Select, pick rows, act

End-to-end: “Select” enters mode → dots morph to rings → tap rows to select → toolbar appears → choose action → feedback → “Done” exits.

Recent
Past 24h
Blue-green deploy rollback procedure2h
OAuth2 token rotation — refresh flow4h
pgvector index tuning — probes=101d
Tailwind v4 migration notes1d
River queue retry backoff config2d
Cohere rerank threshold tuning3d
25d. Move — glass picker anchored to toolbar

“Move” opens a glass picker above the toolbar. Topics with emoji icons. Tap topic → memories move → rows animate out → toast “3 → Deployment” → selection clears.

Move to

Picker anchored to Move button, opens upward. Click outside or Esc closes. Same glass treatment as bar expand slot.

25e. Forget — toolbar morphs to confirmation

Same toolbar container. Actions collapse, destructive confirmation appears. Glassmorphism destructive treatment (kitchen 03). Forget LEFT, Keep RIGHT (cursor safety — cursor was on Forget, Keep appears where cursor is).

Before

After “Forget” tap

Forget 3 memories?
25f. Mobile — long-press entry, compact toolbar

Long-press (500ms, haptic feedback) enters selection on mobile. “Select” text still available in header. Compact toolbar: icons only, same glass treatment. Fixed above safe area.

Recent
Done
Blue-green deploy rollback procedure
OAuth2 token rotation — refresh flow
pgvector index tuning — probes=10
Tailwind v4 migration notes
25g. When batch matters — real user scenarios
Inbox triageWeekly

20 unassigned memories. Select by theme, batch move to topics. Primary batch use case.

Move to topics
Context handoffPer project

Starting new project. Select all auth memories, copy as <memax-context> for agent.

Copy context
Dream cleanupMonthly

After dreams merge duplicates. Forget stale memories the dream engine didn't catch.

Batch forget
Knowledge backupOn demand

Leaving project. Export topic memories as .md file for handoff.

Export .md
25h. State Machine — complete lifecycle

Every batch action follows the same state machine. No dead states, no silent failures.

1
Idle

Normal rows. Category dots. No selection UI visible.

2
Selection active

"Select" → "Done" in header. Dots morph to rings. Click toggles.

3
Toolbar visible

≥1 selected. Glass toolbar at bottom: count + Move/Copy/Export/Forget.

4
Confirm (forget only)

Toolbar morphs in place: "Forget N memories? [Forget] [Keep]".

5
Pending

Toolbar shows spinner + count. Actions disabled. No user interaction.

6
Success

Selection exits. Bar toast: "3 memories forgotten" / "3 memories moved" / "Copied".

7
Error

Selection stays. Bar toast (error): "Failed to forget/move". User can retry.

Pending state (toolbar morphs to spinner)

3 memories...

Success toast (bar notification)

3 memories forgotten

Architecture (for LLM agents)

SelectionProvider— section-scoped (not layout-level). Each section wraps its own provider from the parent (KnowledgeGrid, TopicDetailPage). useSelection() inside the section reads the correct context. Esc exits globally.

BatchToolbar— portals to document.body via createPortal (escapes overflow-hidden + transform ancestors). z-60 (above bar z-50). Signals GlobalBar to hide via batch-active.ts bridge. Slides up (y 24→0, opacity, FAST spring). Uses bar tokens (--bar-bg, --bar-border).

batch-active.ts— module-level signal (same pattern as mutation-toast.ts). BatchToolbar signals active/inactive on mount/unmount. GlobalBar listens: bar slides down + fades (marginTop 0→24, avoids transform conflict with translateX(-50%)). Bar/toolbar share same bottom position — container morphing with animated swap.

MemoryRow— indicator slot morphs dot → ring → check (spring easing, no new DOM). Click: selectionActive ? toggle : navigate. Long-press 500ms on mobile enters selection.

FilterDropdown— portalled to body (escapes card overflow-hidden). Positioned via anchorRef getBoundingClientRect.

Toasts— via MutationCache meta (universal async action pattern, kitchen 28). No per-callsite toast wiring. Callsite callbacks for UI side-effects only (selection.exit()).

Server: POST /v1/memories/batch-delete (single SQL), POST /v1/memories/batch-move (topic or hub). Atomic — zero partial state.

4. Bar States

GlobalBar visual states — border, shadow, and animation combinations.

Unified bar states — 1px border, progressive shadow

All states use 1px border. No border-width changes. Focus adds subtle ring + lift. Active states use notification banner, not border animation.

idle (rest)

idle (rest)

focused (Cmd+K / tap)

focused (Cmd+K / tap)

typing

typing

with notification

with notification

Bar container animations
idle

idle

recall-loading

recall-loading

recall-result

recall-result

remember

remember

Bar notification — type/state/background reference

All barNotification types with their icon, accent color, background, and auto-dismiss behavior. One notification at a time — new replaces old.

TypeIconScenarioAuto-dismissActions
successSent to memax, file imported4s→ view, ✕ dismiss
errorSave failed, invalid file5s✕ dismiss
infoSending... (loading)Replaced by success/error
dreamDream report findings→ report, ✕ dismiss
dreamingDream in progressAuto on complete
updateApp update available→ action, ✕ dismiss

Live background previews per type:

Signature muted Current — dream violet tint

memax dreamed · merged 3 · 1 contradiction
remember, recall, or ask...

Glass frost Subtle neutral frosted glass

memax dreamed · merged 3 · 1 contradiction
remember, recall, or ask...

Dream aurora Purple→blue→pink dream gradient — matches dream cards

memax dreamed · merged 3 · 1 contradiction
remember, recall, or ask...

Success (Sent to memax.) ✓ Sent to memax. · title [Undo] — auto-dismiss 4s

memax dreamed · merged 3 · 1 contradiction
remember, recall, or ask...

Error (Save failed) ✕ Save failed — auto-dismiss 5s

memax dreamed · merged 3 · 1 contradiction
remember, recall, or ask...

Info (Sending...) ✦ Sending... — replaced by success/error

memax dreamed · merged 3 · 1 contradiction
remember, recall, or ask...

Unified: always 1px border (--bar-border at 12% light / oklch(0.30) dark). Focus adds ring + subtle lift. No border-width changes between states. Notification banner provides active state feedback, not the container border.

5. Loading Text

Time-progressive loading with animated star indicators. Each mode has a unique visual identity: sonar rings (recall), pulse dots (ask), settling glow (remember).

Recall mode — sonar rings (searching memory)
Ask mode — pulse dots (thinking)
Remember mode — settling glow (placing memory)

24. Bar Redesign

One bar, two operations. Push (remember) and Recall (search). Notification behind bar. Progressive results.

24a. Push mode — default, zero friction

Default mode. User types, hits Enter (desktop) or send button (mobile). Textarea auto-expands for multi-line. Enter always newline on mobile.

remember, recall, or ask...

Empty — send disabled

Our auth uses JWT + API key dual path

Typing — send enabled

Meeting notes from product review: - Bar redesign approved - Progressive search confirmed - Mobile Enter = newline

Multi-line (auto-expand, Enter on mobile = newline)

Deploy process uses Fly.io with two toml files...

Sending — spinner

24b. Mode switching — visual comparison

One bar, two operations. How does the user choose Push vs Recall? Three approaches compared — Option C (floating mode toggle) was chosen and implemented. Desktop uses subtle text, mobile uses pill chips. All share the same visual language (bar tint + button icon change).

Option A — Dual send buttons (no mode, direct action)

deployment process

Two buttons visible — user picks action

Enter = push, Cmd+Enter = recall. No mode state needed. But no keyword filter while typing (don't know which action user wants).

Option B — Logo toggle (click logo to switch mode)

meeting notes

Push mode (default) — logo normal

deployment process

Recall mode — logo tinted, click to toggle back

Logo is the toggle. Recall mode enables keyword filter while typing. Cmd+K also enters recall mode. Esc exits.

Option C — Floating mode toggle above bar ✓ Implemented

Desktop — subtle text toggle (12px, no fill)

remember·recall
meeting notes

Desktop push — “remember” bold, “recall” muted

remember·recall
deployment process

Desktop recall — “recall” signature color, bar tinted 3%

Mobile — tappable pill chips (44px touch target, 13px font)

↑ remember✦ recall
meeting notes

Mobile push — dark fill on active chip

↑ remember✦ recall
deployment

Mobile recall — signature fill on active chip

Toggle floats above bar with AnimatePresence (slide-up 200ms enter, slide-down 200ms exit). Hidden when: notification visible, recall results expanding, or non-input phase. Smart detection auto-suggests mode but user can always override via toggle.

24c. Progressive recall results — 4-layer loading

Results appear progressively: keyword (0ms) → server FTS (200ms) → semantic (1-3s) → AI synthesis (3-8s, Pro only). User sees results get better over time without waiting.

T=0ms — local keyword filter

auth architecture

Auth Middleware Design

JWT + API key dual path, agent_name from key...

2d

Security Rules

Owner isolation, boundary enforcement...

4d

T=1s — semantic recall ranked

auth architecture

Agent Identity Architecture

98%

Auth = identity. API key → agent_name, OAuth JWT → claim...

Authentication · claude-code · 2d

MCP OAuth JWT Fix

91%

Added AgentName claim to JWT, MCP OAuth tokens carry identity...

Authentication · memax-team · claude-code · 3d

Security Rules

74%

Owner isolation at data layer, every query filters by owner_id...

Security · 1w

T=3s — AI synthesis (Pro)

auth architecture

Agent Identity Architecture

98%

Auth = identity. API key → agent_name, OAuth JWT → claim...

Authentication · claude-code · 2d

MCP OAuth JWT Fix

91%

Added AgentName claim to JWT, MCP OAuth tokens carry identity...

Authentication · memax-team · claude-code · 3d

Memax uses a dual auth architecture: API keys carry agent_name for CLI/MCP connections, while OAuth JWTs embed agent_name as a claim for Claude Desktop. The middleware unifies both paths — GetAgentName() reads from either source, with API key taking priority over client params to prevent spoofing.

Complete — AI answer + sources

auth architecture

Agent Identity Architecture

98%

Auth = identity. API key → agent_name, OAuth JWT → claim...

Authentication · claude-code · 2d

MCP OAuth JWT Fix

91%

Added AgentName claim to JWT...

Authentication · memax-team · claude-code · 3d

Memax uses a dual auth architecture: API keys carry agent_name for CLI/MCP connections, while OAuth JWTs embed agent_name as a claim for Claude Desktop. The middleware unifies both paths — GetAgentName() reads from either source, with API key taking priority over client params to prevent spoofing.

24d. Free vs Pro — synthesis gated

Free — keyword + semantic only

deployment

Deployment Process

95%

Fly.io two-process deploy...

CI/CD Pipeline

78%

GitHub Actions workflow...

AI answers available on

Pro — auto AI synthesis

deployment

Deployment Process

95%

Fly.io two-process deploy...

Deploy uses Fly.io with two processes: API server (fly.server.toml) and worker (fly.worker.toml). Run fly deploy -c fly.server.toml for the API...

24e. Send button — all states

Push empty

Push ready

Sending

Recall empty

Recall ready

Push: dark fill (↑ ArrowUp). Recall: signature fill (✦ Sparkles). Loading: spinner replaces icon. Disabled: ghost, /40 opacity.

24f. Mobile — Enter=newline, auto-expand, photo picker

Mobile Enter always inserts newline — send button is the only way to submit. Textarea auto-expands via field-sizing: content (scrollbar hidden). Mode toggle uses tappable pill chips. Camera/file icon visible when input is empty.

remember, recall, or ask...

Mobile — 1 line + camera icon

Line one of my note Line two continues Line three gets long

Mobile — multi-line (auto-expand, scrollbar hidden)

what do I know about deploy

Mobile — recall mode with pill chips

Industry standard (ChatGPT, Claude, iMessage): auto-expand + scroll within bar. No fullscreen compose mode — keeps context visible. Scrollbar hidden via scrollbarWidth: none.

24g. File & attachment push — drag, paste, bulk

Files are staged above the input row as chips. Multiple files batch into one push. Images from clipboard auto-stage. Drag-drop onto bar. URL paste auto-detects and offers capture.

screenshot.png

Auth flow diagram

Single image pasted — chip above input

design-spec.md
mockup.png
notes.pdf

Design review materials

Batch — 3 files dragged, text optional

github.com/MemaxLabs/memax/pull/42
Capture page

remember, recall, or ask...

URL pasted — auto-detect, offer capture

Drag-drop — bar highlights as drop zone

Drop files here...

InputDesktopMobile
Image pasteCmd+V → auto-stage as chipLong-press paste → auto-stage
File drag-dropDrag onto bar → dashed border → drop → stageN/A (no drag on mobile)
URL pastePaste URL → chip + “Capture page” buttonSame
Batch filesMulti-select drag or Cmd+V multiple → all staged as chipsPhoto picker → multi-select → stage
Text + filesOptional — text becomes memory title/note, files are attachmentsSame
Mobile photoN/A📷 icon next to send button → camera/gallery picker
24h. Notification — independent card behind bar

Notification is a separate fixed element (z-49) behind the bar (z-50). Slides up from behind. Own border-radius, own background. Zero seam line — completely independent DOM elements.

Success — 4s undo window, then auto-dismiss. Undo restores content to input + deletes memory.

Sent to memax. · → Auth Architecture · [Undo]
remember, recall, or ask...

Error — auto-dismiss 5s

Save failed · Network error
remember, recall, or ask...

Recalling — dismiss cancels

Searching your knowledge...
remember, recall, or ask...

Dream report — persistent

memax dreamed · merged 3 · 1 contradiction
remember, recall, or ask...

Dream in progress — auto-dismiss on complete

Dreaming... · organizing your knowledge
remember, recall, or ask...
24k. Push flow — state transition chain

Notification transitions in-place behind bar. Each state replaces the previous — no stacking, no flicker.

T=0ms — user hits Enter. Input clears. Notification slides up behind bar.

Sending...
remember, recall, or ask...

T=instant — API accepted. Notification replaces in-place. Auto-dismiss 4s.

Sent to memax. · → Auth Architecture
remember, recall, or ask...

Error — notification replaces in-place. Content restored to input.

Save failed. · Network error
Our auth uses JWT + API key dual path...
StateNotificationBar inputTransition
IdleNonePlaceholder→ Remembering (on Enter)
Sending✦ Sending... (info, optimistic)Cleared→ Sent (success) or → Error
Sent✓ Sent to memax. → title [Undo] (success, 4s window)Ready for new input→ Idle (auto-dismiss) or → Undone (undo clicked)
UndoneDismissed — content restored to inputContent restored→ Idle (instant)
Error✕ Save failed (error, 5s auto-dismiss)Content restored→ Idle (dismiss) — user can retry
24l. Recall flow — state transition chain

Recall has a longer lifecycle. Notification shows during initial search, then dismisses when results take over. AI synthesis is inline in results — no separate notification.

StateNotificationBar expandBar inputTransition
IdleNoneEmptyQuery text→ Searching (on Enter)
Searching✦ Searching... (recalling type, × cancels)Keyword results (instant)Shows query (editable)→ Results (semantic ready)
ResultsDismissed — results speak for themselvesRanked resultsQuery preserved→ Synthesizing (Pro, auto)
Synthesizing(Pro)NoneResults + ✦ streaming belowQuery preserved→ Complete (stream done)
CompleteNoneResults + AI answer + [copy]Query preserved→ Idle (Esc layered: clear query → dismiss results)
Error✕ Search failed (error, 5s auto-dismiss)EmptyQuery preserved→ Idle (dismiss) — user can retry

Key rule: notification only during the “Searching” phase. Once results appear, notification dismisses — results are the feedback. AI synthesis uses inline ✦ cursor, not a notification.

Searching — notification active, keyword results appearing

Searching your knowledge...

auth architecture

Auth Middleware Design

JWT + API key dual path...

Results ready — notification gone, results are the feedback

auth architecture

Agent Identity Architecture

98%

Auth = identity. API key → agent_name...

claude-code

MCP OAuth JWT Fix

91%

Added AgentName claim to JWT...

claude-code

Security Rules

74%

Owner isolation at data layer...

Memax uses a dual auth architecture: API keys carry agent_name for CLI/MCP, while OAuth JWTs embed agent_name as a claim for Claude Desktop...

24i. Keyboard shortcuts & behavior
ActionDesktopMobile
Send (push/recall)EnterSend button tap
NewlineAuto-expand (field-sizing: content)Enter (always newline)
Switch to RecallClick “recall” toggle / smart detectionTap “✦ recall” chip
Back to PushClick “remember” toggleTap “↑ remember” chip
Dismiss resultsEsc (layered)Tap outside / X
Focus barCmd+K / clickTap bar
Expand (multiline)Auto (field-sizing)Auto + expand icon at 3 lines
Voice (future)Mic icon in send areaMic icon in send area
24j. Mode toggle — interaction detail

Mode toggles float above bar. Desktop: subtle text toggle (“remember · recall”). Mobile: pill chips with icons. Smart detection from detectIntent() auto-suggests mode. User can always override by tapping toggle.

1. Default mode is “remember” (push) — active text is bold fg-1

2. Click “recall” → logo tints signature, button becomes ✦, bg gets 3% tint

3. Smart detection: question words (what/how/why/是否/什么...) or auto-suggest recall mode

4. Toggle stays visible during input phase — user may want to override

5. Toggle fades out (slide-down, 200ms) when recall keyword results expand

6. Toggle fades back in (slide-up, 200ms) when results clear

7. Toggle hidden when notification is showing (mutually exclusive position)

Desktop — subtle text toggle

remember·recall

Mobile — tappable pill chips (44px touch)

↑ remember✦ recall

6. Tree Panel

Knowledge tree navigation. Three responsive modes: desktop pinned (content shifts), desktop overlay (floats on top), mobile master/detail (Notion-style push). Reuses TopicTreeNode, TopicTreeContent patterns.

22a. Desktop — pinned sidebar (content shifts right)

Full-height sticky sidebar. Logo stays fixed (same position always). Tree header aligns with CONTENT_TOP. ChevronsLeft collapses. Content push animated via motion.div width 0↔280. Hover left edge reveals overlay. Persisted.

Knowledge
Deployment23
Staging8
Production11
Rollback4
Authentication18
OAuth6
Tokens5
Go Patterns31
Database15
Frontend22
Team Docs9
3 unassigned memories

Content shifts right

Sidebar takes space in layout flow

22b. Desktop — hover-reveal overlay (peeking)

No toggle button. Hover left edge (12px zone, 150ms delay) reveals overlay. Starts at HEADER_TOP (not full height). » pins to layout flow. Mouse-leave dismisses after 300ms. Backdrop at 8% opacity.

Content stays full width

Hover left edge to reveal

22c. Mobile — bottom sheet (current production)

ListTree icon next to “Your Knowledge” page header (right side). Opens bottom sheet overlay with drag handle. Toggle is contextual, not in fixed header.

Your Knowledge

10 memories · 5 topics

Knowledge
Deployment23
Staging8
Production11
Rollback4
Authentication18
OAuth6
Tokens5
Go Patterns31
Database15
Frontend22
Team Docs9
3 unassigned memories
22d. Mobile — master/detail push (target, Notion-style)

Tree IS the page content. Tap a topic → detail slides in from right. Back arrow returns. No separate toggle button. No overlay. This is the target pattern for mobile knowledge navigation.

Your Knowledge

147 memories · 6 topics

Deployment23
Authentication18
Go Patterns31
Database15
Frontend22
Team Docs9

Topic detail

Memory list here

22e. Tree node states

Collapsed (has children)

Deployment23

Active (selected)

Deployment23

Leaf (no children)

Go Patterns31

Drop target (DnD hover)

Database15
22f. Empty states — pre-dream, dreams off

Waiting for first dream

Topics appear after your first dream

memax organizes your memories during the nightly dream cycle.

Dreams disabled

Dreams are turned off

Enable dreams to organize your knowledge.

Production files: topic-tree-panel.tsx (provider + pinned/peek), topic-tree-content.tsx (data + empty states), topic-tree-node.tsx (recursive node). layout.tsx (SidebarSlot, DesktopTreeHoverEdge, BrandLogo).

Desktop: pinned (sticky, ChevronsLeft) → collapsed (invisible) → hover left 12px zone (150ms) → overlay (top:HEADER_TOP, ChevronsRight to pin) → pinned. Content push: motion.div width 0↔280. isPinned in localStorage.

Mobile: ListTree icon in page header (topic-grid.tsx) opens bottom sheet. No fixed toggle button. Future target: master/detail push (22d).

7. Hub Experience

Team hub: ambient workspace switching via avatar dropdown (top-right), memory attribution, management, invite. Personal by default, team by intent.

20a. Hub switcher — avatar dropdown (top-right)

Integrated into existing avatar dropdown (top-right). Single-hub users see no hub section. Multi-hub: hub list appears between user info and theme/lang toggles. Active hub shown with checkmark. Users icon for team hubs. “Create team hub” link at bottom. Current hub name shown in user subtitle.

Single hub user (no hub section)

D

Derek

52 memories

🌙 Dark
EN / 中

Multi-hub user (hub switcher in dropdown)

D

Derek

backend-team · 31 memories

Personal52
backend-team31
design-team12
Create team hub
🌙 Dark
EN / 中
20b. Memory attribution — hub badge on rows

Team memories show lucide Users + hub name (text-[12px] text-fg-4). Personal memories show no badge (default = no label). Only visible when user has 2+ hubs. Processing row unchanged. Flat dividers, icon containers match production.

Recent
D
Derek via Claude CodeAPI authentication flow3d

OAuth2 refresh flow with token rotation strategy...

architecture·Personal auth notesweb5d
Deploy runbook updateorganizing...
20c. Hub-aware bar behavior

Push toast: “Sent — memax will organize.” (personal) or “Sent → hub-name — memax will organize.” (team). Recall results show hub attribution in cross-hub mode. Bar clears immediately after submit (chat-style, no blocking confirmation).

Push to personal hub (toast, no hub label)

Sent — memax will organize.

Push to team hub (toast with target)

Sent → backend-team — memax will organize.

Recall results (cross-hub, shows attribution)

API authentication flowbackend-team92%
My personal auth notes87%
Auth middleware architecturebackend-team84%
20d. Hub creation (settings Account tab)

Inline form in settings dialog Account tab, below existing hub list. Name input → auto-generated slug → Create. Hub appears in pill dropdown immediately. Also accessible via dropdown “Create team hub” link.

Workspace

Personal52 memoriesactive
backend-team31 memories

Create team hub

Your team will share a knowledge base. Invite members after creation.

20e. Hub management (settings, expandable per hub)

Click team hub in settings → expands to show members + invite link. Flat row dividers. Role badges. Copy invite link. Owner/admin only. Same Surface pattern as memory detail.

backend-teamteam

5 members · 31 memories · created 2w ago

D
DerekOwner2w ago
S
SarahAdmin1w ago
J
Jamescontributor3d ago
A
Alexcontributor3d ago
P
Priyaviewer1d ago

Invite link

https://memax.app/invite/a8f3c2e9...

Expires Apr 12, 2026

20f. Invite accept page (/invite/[token])

Centered card, same visual language as login. Shows hub name, memory count, member count, inviter. Single CTA. Expired tokens show error state.

Join backend-team

31 shared memories

5 members

Invited by Derek

Search and contribute to
your team's shared knowledge.

Expires Apr 12, 2026

20g. Hub-scoped inbox states

Inbox is hub-scoped. Shows unassigned memories for active hub. Clean state uses DREAM_PURPLE ✦. All states match production patterns (Clock/Inbox icons, flat dividers, icon containers).

Team inbox (has items)

Inbox4

Will be organized in the next dream cycle

Will be organized in the next dream cycle

note·Staging deploy checklist2h
note·Meeting notes — API review5h

Inbox clean

Inbox0

Your memory is clean

20h. Hub creation states

All states for hub creation: loading (breathing ✦), error (inline message), success (auto-switch + open management). Maps to teams-section.tsx HubCreateForm.

Creating

Error

Hub name already taken

Success → management

design-team createdAuto-switches + opens management
20i. Empty hub onboarding (just created, alone)

When hub has 1 member (owner) and 0 memories, replace member list with prominent invite CTA. This is the first thing an owner sees after creating a hub.

design-team

1 member · 0 memories · just now

Invite your first teammate

Share a link to start building shared knowledge.

20j. Invite link states

Four states: not generated (CTA button), generating (breathing ✦), generated (code + copy + expiry), error (inline message). Maps to hub-management.tsx InviteLinkSection.

Not generated

Generating

Generated

https://memax.app/invite/a8f3c2e9...

Expires Apr 14, 2026

Error

Could not generate invite link.

20k. Invite accept page — all states

Logged in: single CTA. Not logged in: “Sign in to join” → OAuth → return to page → auto-accept. Expired/used show error. Accepted shows redirect.

Logged in

Join backend-team

5 members · Invited by Derek

Not logged in

Join backend-team

5 members · Invited by Derek

→ OAuth → returnTo in localStorage → auto-accept on return

Expired

Invite expired

Ask the hub owner for a new link.

Accepted

Joined!

Redirecting to your team's memory hub...

20l. Delete hub confirmation

Two-step: button → destructive confirmation with memory count + member impact. “Personal memories are not affected.” After delete: return to list, auto-switch to personal.

Default

Confirmation

Permanently delete backend-team and all 31 memories. 4 members will lose access.

Personal memories are not affected.

20m. Role-based management views

Owner/Admin: full management (members + invite + delete). Contributor/Viewer: read-only member list + leave only. Roles affect ACTIONS not VIEWS — all roles see the same memories.

Owner / Admin

D
Derekowner
S
Sarahadmin
J
Jamescontributor

Contributor / Viewer

D
Derekowner
S
Sarahadmin
J
Jamescontributor

No invite button. No delete. Read-only member list + leave only.

20o. Hub Scope Filter — view + push

Hub switcher = scope filter. Selection controls BOTH what you see (read) AND where you push (write). “All” is read-only aggregation — push defaults to personal. Single-hub users see no filter UI.

Hub scope selector (in dropdown)

D

Derek

All · 95 memories

Push → Personal

Scope model

AllRead: everything·Push: → personal
PersonalRead: personal only·Push: → personal
TeamRead: team only·Push: → team

Recall always crosses all hubs.

Regardless of view scope, recall searches everything accessible. Hub badges on results show origin.

20p. View titles per scope

Knowledge page title adapts to active scope. Personal = “Your Knowledge”, Team = “{name}'s Knowledge”, All = “All Knowledge”. Breadcrumb root also adapts.

Scope: All

Active scope

All Knowledge

95 memories · 8 topics

Scope: Personal

Active scope

Your Knowledge

52 memories · 5 topics

Scope: Team

Active scope

backend-team's Knowledge

31 memories · 3 topics

20q. Push target indicator

Bar shows where push goes. Personal scope: no indicator (default). Team scope: hub name pill right of input. All scope: “→ Personal” default, user can tap to change. Push toast always confirms target.

Bar — team scope (push target shown)

type to remember, ask to recall...backend-team

Bar — personal scope (no indicator needed)

type to remember, ask to recall...

Bar — “All” scope (push defaults to personal)

type to remember, ask to recall...Personal

Push toasts by scope

Sent — memax will organize.(personal scope)
Sent → backend-team — memax will organize.(team scope)
Sent — memax will organize.(“All” scope → defaults to personal)

Push target rules:

• Personal scope → push to personal hub (no indicator)

• Team scope → push to that team (arrow pill indicator)

• All scope → push to personal (muted indicator, tappable to switch)

• Single-hub users → no scope UI, no push indicator

20n. Hub switch feedback

Uses existing bar notification system. Success type, 2s auto-dismiss. Avatar subtitle updates immediately. No new component.

After switching hub in dropdown, bar shows confirmation notification. Avatar subtitle updates immediately.

Switched to backend-team
remember or recall...

Success type, 2s auto-dismiss. Uses existing bar notification system. No new component needed.

7r. Profile — display name edit

In settings Account tab. Click name → inline edit → save on blur/Enter. display_name is the single source of truth (seeded from OAuth, editable here). Used in attribution rows, settings panel, avatar dropdown.

J

yejiahaoderek@gmail.com

free

Inline edit: no modal, no save button. Bottom border appears on hover, solidifies on focus. Save on blur or Enter. PATCH /v1/auth/me with display_name. Optimistic update in useAuth.

Industry pattern: Slack, Notion, Linear, Vercel, GitHub, Figma all use top-left scope selector. 2-click standard. Full context swap on switch.

Routing: switched hub sets read context only. Push writes require explicit targeting (for example X-Hub-ID) or fall back to personal. Recall reads across all accessible hubs.

New user invite flow: Click link → see hub info → “Sign in to join” → OAuth with returnTo → auto-accept on return → switch to hub → land in /home.

23. Agent Management

Unified agent identity, API keys, config sync, activity stats. Settings > Agents tab northstar.

23a. Northstar — Agent Overview

Each connected agent gets a unified card. Identity icon with accent color, status dot (active/idle/inactive), stats summary. Expand for API keys, config files, rename, revoke.

claude-code

API Keys

mxk_a1b2····All hubs2m ago
mxk_c3d4····memax-team1h ago

Synced Configs· 30 extracted

CLAUDE.mdv1
CLAUDE.md5v3
MEMORYindex8v1
Design Patternsfeedback3v1
Container Morphingfeedback2v1
CLAUDE.md12v2
147 memories pushedLast active 2m ago
23b. Rename — inline edit

User can customize the display name shown in memory attribution and across the app. The agent slug (claude-code) is immutable — set during memax setup. Priority: user custom → AGENT_NAMES map → raw slug.

Display mode

Claude Code

claude-code

Editing mode

claude-code

Enter to save

Display name is user-customizable. Slug (claude-code) is immutable, auto-set from agent type during memax setup. Display name flows to memory attribution.

23c. Revoke & Disconnect

Three levels of removal: revoke single key, revoke all keys for an agent, or full disconnect (keys + configs). Memories are always preserved — they belong to the user, not the agent.

Normal state

mxk_a1b2····All hubs2m ago

Revoke confirmation

Revoke mxk_a1b2? Agent will lose access.

Disconnect agent (revoke all keys + delete configs)

Disconnect Claude Code? 2 keys and 6 configs will be removed. Memories are preserved.

Two-stage confirmation pattern. Revoking a single key is granular. “Disconnect agent” revokes all keys + deletes all configs for that agent. Memories pushed by the agent are always preserved (they belong to the user, not the agent).

23d. Activity Status

Status derived from last_usedon API keys. No MCP polling needed — every API call updates the timestamp.

Active now2m agoAPI key used within last 24h
Idle3d agoLast used 1-7 days ago
Never connectedNever used or >7 days
23e. Agent Identity System

Each agent type gets a unique icon + accent color. Consistent across attribution, settings, and management surfaces. Icon is mapped from agent_name slug, not user-configurable (keeps visual consistency).

Claude Code

claude-code

Claude

claude-ai

Cursor

cursor

Codex

codex

Gemini CLI

gemini

GitHub Copilot

copilot

Windsurf

windsurf

OpenClaw

openclaw

OpenCode

opencode

Other

generic

Memax Agent

memax

23f. Empty State — no agents connected

Loading

No agents

Connect your first agent

Claude Code, Cursor, Windsurf, Copilot, Codex, Gemini

npm i -g memax-cli && memax setup

Data model

Agent identity is derived from api_keys.agent_name — set during memax setup. Each agent type can have multiple keys (per-hub, per-device). Activity status from api_keys.last_used.

Display name priority: user custom → AGENT_NAMES map → raw slug. Stored as agent_display_name on api_keys (future migration). Unified constant shared across memory-row, settings, and attribution.

New endpoint needed: GET /v1/agents/summary — aggregates api_keys + configs + memory counts per agent_name.

Production files: agent-configs-section.tsx, settings-dialog.tsx, memory-row.tsx. API: GET /v1/auth/api-keys, GET /v1/configs.

10. Dream Experience

Dream reports, action cards, and review flows. Background intelligence made visible. Premium visual treatment with dreamy purple/blue/pink palette.

9a. Dream report card — 6 states

Dreams haven't run yet

They run nightly to organize your memory

Dreaming…

Scanning 247 memories

Last night · 247 scanned
3 notes merged
1 contradiction found
2 notes archived

Your memory is clean

Dream failed

Processing timed out. Your memories are safe.

Dreams are turned off

9b. Dream action cards
Merged 2 notes about React Server Components

92% similarity

kept: Server components render on the server and send HTML to the client.

merged: RSC renders server-side, sending HTML.

Archived stale note

Last accessed 90 days ago. No recent recalls matched.

Found conflicting information

Two notes disagree about the default cache TTL.

9c. Dream review cards
Conflicting cache TTL values

87% similarity · both mention Redis cache configuration

Note A

“Default cache TTL is 3600 seconds (1 hour)”

Note B

“Set cache TTL to 1800s for optimal performance”

Resolved: kept both versions2d ago
No reviews pending
9d. Conflict card stack (Robinhood-style)

Cards stacked visually. Resolve top card → it flies away, next card springs forward. Stack depth shows remaining count. Interactive demo below.

Conflicting cache TTL values87%

A

Default cache TTL is 3600 seconds (1 hour)

B

Set cache TTL to 1800s for optimal performance

0/3

i18n keys: dreams.noRuns, dreams.running, dreams.completed,

dreams.clean, dreams.failed, dreams.disabled, dreams.merge,

dreams.archive, dreams.contradiction, dreams.review.*

Dreams are passive — surface results gently, no forced interruptions. Contradictions need human judgment (amber = attention, not urgency). Purple/blue/pink = dream visual language. Card stack: Robinhood-style stacked resolution — resolve top card, next appears.

29. Topic Redesign

Three-tier topic cards, 'what's new' signal, recall→topic bridge, borderless detail. MECE: Browse, Find, Review, Organize, Discover, Export.

29a. Topic card tiers — grid with mixed sizes

One component, three tiers based on memory count. Large spans 2 cols on desktop. "N new" uses typographic weight + Dream Violet left accent. Progress bar shows relative size.

Deployment

Blue-green deploys, rollback procedures, staging automation, Fly.io machine health checks

StagingProductionRollback
47 memories·3 subtopics·5 new
Auth & Security

JWT tokens, OAuth, API key rotation, boundary enforcement

23 memories·2 new
Go Patterns

Error handling, context propagation, interface design

31 memories
Frontend

React Server Components, Tailwind, Radix primitives

22 memories
Database

PostgreSQL, pgvector, migrations, connection pooling

15 memories·3 new
CI/CD(4)
Testing(3)
Compliance(2)
Redis(1)

Large (20+): 2-col span, progress bar, subtopic chips, full description

Medium (5-19): standard card, name + desc + count

Small (1-4): horizontal scroll pills, minimal

"N new": text-fg-2 font-medium + shadow lift (no border accent)

29b. What's new signal — comparison

No new content

Go Patterns

Error handling, context propagation

31 memories

3 new since last visit

Auth & Security

JWT tokens, OAuth, API key rotation

23 memories·3 new

Left: clean, no accent. Right: "3 new" at text-fg-2 font-medium + shadow lift (no left border). Client-side localStorage per-topic timestamps.

29c. Recall → topic bridge (grouped results)

Recall results grouped by topic. Topics with >1 match get a clickable header row. ✦ prefix on dream-discovered topics.

Auth & Security(3 matches)
1OAuth Token Refresh92%
2JWT Validation Strategy87%
3API Key Rotation81%
Deployment(1 matches)
4Staging Deploy Guide78%

Topic rows: icon + name + match count + → chevron. ✦ prefix for dream-discovered. Individual results indented (px-6). Uses topic_id + topic_name from RecalledMemory.

29d. Topic detail — borderless (matching memory detail)
Your KnowledgeAuth & Security
Auth & Security

JWT tokens, OAuth flows, API key management, boundary enforcement, and security audit results.

23 memories·3 subtopics·Updated 2h ago
Copy 23 for AI
Since your last visit · Apr 5
API key rotation policy update3h ago
OAuth refresh token audit3h ago
JWT validation middleware1w
Security review Q1 decisions3w

Borderless on --background. Breadcrumb → icon + name (editable) → description → meta

Time boundary: centered divider with last visit date. New memories above, old below.

Copy button: "Copy N for AI" — exports all topic memories for context.

29e. Mobile grid layout
Knowledge Tree
Deployment

Blue-green deploys, rollback procedures

47 memories·3 subtopics·5 new
Auth & Security

JWT tokens, OAuth

23 memories·2 new
Go Patterns

Error handling, context

31 memories
CI/CD(4)
Redis(1)
Misc(2)

Mobile: single column. Large = full card. Medium = compact. Small = horizontal scroll pills. Tree trigger as discoverable row at top.

29f. Dream discovery — new topic ✦

Existing topic

Go Patterns

Dream-created topic

CI/CD Pipeline

✦ prefix on dream-created topics (created_at after last dream run). Disappears after first visit. Dream Violet signals "AI found this."

Design rules — topic system
1.

Three tiers. Large (20+ or has children) spans 2 cols. Medium (5-19) standard card. Small (1-4) horizontal scroll pills. One component with tier prop.

2.

"N new" via typography + shadow. text-fg-2 font-medium + shadow lift (no left border accents). No badges, no dots. Client-side localStorage per-topic timestamps.

3.

Recall → topic bridge. Group results by topic_id. Clickable header row with match count. ✦ prefix on dream-discovered topics.

4.

Borderless detail.Topic detail matches memory detail — content on --background. Time boundary for "since your last visit."

5.

Mobile is structural. Single column grid. Small topics = horizontal pills. Tree trigger as discoverable row.

6.

Progress bar = relative size. Largest topic = 100%. Others proportional. bg-surface-2 track, bg-surface-3 fill. No color.

21. Explorations

Proposed / Not Yet Implemented

Proposed / Not Yet Implemented

Signature color proposals

Option A

#e8956a warm peach

Option B

#d4845e terra

Option C

#c9916e sand

Current (emerald)

#10b981 emerald

Navigation dots
home
memories
dreams
settings
Ghost card breathing

22. Coverage Gaps

State coverage matrix — what's implemented, partial, or missing across every surface.

Status matrix
LocationLoadingEmptyErrorProcessing
Bar recall
Bar remember
Bar AI synthesis⚠️
Memory grid⚠️
Note detail⚠️
Settings
Brain view

✅ implemented · ⚠️ partial · ❌ missing · — N/A

Priority: error states across bar + memory grid + settings

memax design system · Foundations → Components → Patterns · docs/design/memax-design-system.md