Patterns
Surface layering, interaction affordances, information hierarchy, and UI composition best practices for building Inkwell interfaces.
Surface Layering
Surfaces create depth through nested backgrounds, multi-layer shadows, and edge highlights. In dark mode, edge-light replaces shadow as the primary depth cue. Click levels to see progressive elevation.
Multi-Layer Shadow System
Never use a single box-shadow. Real depth requires at minimum two layers (contact + ambient), ideally three. Each elevation level gets progressively larger, softer, more diffuse shadows.
Level 1 — Subtle lift
Cards, inputs, badges
Contact: 1px blur, 5% opacity
Ambient: 3px blur, 8% opacity
Level 2 — Clear elevation
Dropdowns, popovers, tooltips
Contact: 2px blur, 6%
Penumbra: 8px blur, 8%
Ambient: 24px blur, 6%
Level 3 — High elevation
Modals, command palette, toasts
Contact: 3px blur, 8%
Penumbra: 16px blur, 8%
Ambient: 48px blur, 6%
Hairline: 1px solid, 2%
Why multi-layer?
A single box-shadow looks artificial. Real depth has contact occlusion (tight, close), penumbra from the primary light (mid-range), and diffuse ambient shadow (large, soft). Each layer has its own blur radius and opacity, growing softer and more spread at higher elevations.
Edge-Light & Dark Mode Depth
Light mode uses shadows for depth. Dark mode shifts to edge-light — subtle bright top/left borders that define shape boundaries through rim-light, since shadows become invisible against dark backgrounds.
Light Mode — Shadow-Dominated
On light backgrounds, shadows are the primary depth cue. Edge highlights are subtle or absent.
Dark Mode — Edge-Light-Dominated
On dark backgrounds, shadows vanish. Bright top/left edges (rim-light) become the primary form-definition mechanism.
Panel Background Modes
Panels support two rendering modes: solid (opaque card) and translucent (frosted glass with backdrop-blur). Configurable per user preference in Settings > Appearance.
Solid
INT. COFFEE SHOP – MORNING
Rain streaks the window. A WRITER stares at a laptop, cursor blinking on line one.
WRITER
(muttering)
Every great screenplay starts with a blank page.
She closes the laptop. Picks up a pen. Begins writing by hand.
CUT TO:
Opaque card surface via --panel-solid-bg. Editor content is fully hidden. Maximum legibility.
Translucent + Blur
INT. COFFEE SHOP – MORNING
Rain streaks the window. A WRITER stares at a laptop, cursor blinking on line one.
WRITER
(muttering)
Every great screenplay starts with a blank page.
She closes the laptop. Picks up a pen. Begins writing by hand.
CUT TO:
Frosted glass via --panel-translucent-bg + backdrop-blur(16px). Editor content is visible through the sidebar, creating spatial depth.
Interactive Preview
INT. COFFEE SHOP – MORNING
Rain streaks the window. A WRITER stares at a laptop, cursor blinking on line one.
WRITER
(muttering)
Every great screenplay starts with a blank page.
She closes the laptop. Picks up a pen. Begins writing by hand.
CUT TO:
Draft
12,847
3 min ago
Color Rarity Principle
90%+ of the interface should be neutral chrome. Color is conspicuous by its rarity — when everything is colored, nothing stands out. Reserve saturated hues for active states, errors, and primary actions.
Correct — color is rare
90%+ neutral chrome. The single blue accent draws the eye to the active item. Color has meaning because it is rare.
Incorrect — color overload
Every element uses a different color. Nothing stands out. The eye bounces between hues with no hierarchy. Color has no semantic weight.
Opacity Hierarchy
Vary opacity across layers to create atmospheric depth. Primary content at full opacity, secondary at 60-70%, and ambient elements at 4-12%. The variation itself is the depth cue.
The variation in opacity creates atmospheric perspective — the same principle that makes distant mountains appear lighter. Uniform opacity across all elements flattens the composition.
Visual Hierarchy — Labels vs Values
Values must be more prominent than labels. Labels recede (small, muted, uppercase); values stand out (normal size, medium weight, foreground color).
Correct — values dominate
Alt ending — happy
2 minutes ago
12,847
Incorrect — labels dominate
Alt ending — happy
2 minutes ago
12,847
Data Density
Three density levels for lists and tables. Default suits most contexts; compact serves power users; comfortable improves readability for extended use.
compact
Maximum information per screen. For power users who scan lists quickly.
default
Balanced padding and spacing. Suitable for most contexts.
comfortable
Extra breathing room. For focused reading and accessibility.
Interaction Affordances
Every interactive element communicates its interactivity through cursor changes, hover states, focus rings, and visual feedback.
Hover Reveal
Secondary actions appear on hover. Primary content stays visible.
Scene 12
INT. COFFEE SHOP - MORNING
Progressive Disclosure
Details expand on demand. Chevron rotation signals state.
Toggle States
Color shift and thumb translation communicate binary state.
Drag Handle
Grip icon signals reorderability. Cursor changes to grab on hover.
Scene 5
EXT. ROOFTOP - NIGHT
Focus Indicators
2px ring with 2px offset. Visible on all backgrounds. Tab to see.
Cursor & Press States
Cursor shape signals type. Press feedback (translateY, shadow shrink) confirms action.
Inline Edit Affordance
Editable text has a dashed underline on hover. Click to enter edit mode with a visible input border.
Untitled Screenplay
LoglineA writer discovers that the stories they write come true...
Spatial Grammar
Consistent spacing hierarchy creates visual grouping through proximity. Each level is ~2x the level below — breaking this ratio destroys grouping.
Geometric Progression (each level ≈ 2× the one below)
Label ↔ Value
Tightest grouping — text pairs
Items in group
List items, form fields
Groups in section
Card content areas
Content sections
Major content zones
Page sections
Top-level layout divisions
Hierarchical spacing
Act 1 — Setup
Scene 1
INT. OFFICE - DAY
Scene 2
EXT. PARK - NIGHT
Scene 3
INT. CAR - EVENING
Uniform spacing (anti-pattern)
Act 1 — Setup
Scene 1
INT. OFFICE - DAY
Scene 2
EXT. PARK - NIGHT
Scene 3
INT. CAR - EVENING
All gaps 12px. Label, title, and list items blur into a single undifferentiated block. No proximity-based grouping.
Perceptual correction
Dense/dark elements appear closer than light/sparse ones at the same pixel gap. Compensate by adding 1-2px extra space around visually heavy elements. The 8px grid is a starting point — break it for optical balance.
Interaction Feedback Loop
Every user interaction follows a 4-stage loop: Discover → Initiate → Process → Confirm. Breaking any stage creates confusion.
Discover
"I can do X"
Hover state, cursor, focus indicator
Initiate
"I chose to do X"
Button disabled + spinner, inputs lock
Process
"System is working"
Skeleton, spinner, or progress toast
Confirm
"It worked"
Success toast, error UI, or undo
Confirmation by Risk Level
Match the confirmation pattern to the risk of the action, not a one-size-fits-all dialog.
| Risk Level | Pattern | Example |
|---|---|---|
Reversible, low | No confirmation — undo toast (10s) | Add scene note, toggle focus mode |
Reversible, moderate | Inline popover with confirm/cancel | Rename draft line, reorder scenes |
Irreversible, moderate | Dialog with change summary | Create save point, run skill, export PDF |
Irreversible, high | Dialog + typed confirmation | Delete draft line, delete project |
Component States
Every component with async data must handle loading, empty, error, and success states visually.
Loading — Skeleton
Skeletons preserve layout and reduce perceived wait time. Never use bare "Loading..." text.
Empty State
Empty areas must explain why they're empty and provide an action to populate them.
No save points yet
Create your first save point to start tracking changes to your screenplay.
Error State
Errors must be visible, human-readable, and provide a recovery action.
Failed to load version history
Check your connection and try again.
Success / Confirmation
Confirmations match the risk level of the action. Low-risk uses toast, high-risk uses dialog.
Save point created
"Add Act 3 revision" — 12,847 words
Domain Vocabulary
Never use Git terminology in user-facing UI. Map to writer-friendly Inkwell terms.
| Git Term | Inkwell Term | Notes |
|---|---|---|
| commit / snapshot | save point | Content-addressable, immutable |
| branch | draft line | Parallel versions of a document |
| diff | changes / markup | Semantic, node-level |
| merge | incorporate | Brings changes from one draft line into another |
| worktree | take | Parallel versions of a scene/act |
Key Principles
Design system principles that apply across all Inkwell interfaces.
Tokens, not hardcodes
Every color, spacing, and motion value must come from a token. No hex values, no magic numbers.
Dark-first design
Design for dark mode first. Light mode is the variant, not the default. All tokens have dark-mode values.
Multi-signal encoding
Never convey information through color alone. Use color + shape + text for accessibility.