Files
typst-leaf/DESIGN.md
T
nav.sikand ae0d888ddf feat: complete UI redesign — editorial-paper palette, Monaco theme, lucide icons, primitives
Palette overhaul:
- Warm cream canvas (#faf8f4) + near-white surfaces (#fdfdfb) + deep teal accent (#0f766e)
- Unified on stone-warm neutrals via @theme block in index.css

Typography:
- Inter Variable + JetBrains Mono Variable via fontsource (self-hosted)
- Monaco editor set to JetBrains Mono for consistency

Icons:
- lucide-react replaces all 8 hand-rolled SVGs
- Leaf brand mark beside wordmark

Shared primitives (src/components/ui/):
- Icon, Button (4 variants, 2 sizes), IconButton, TextInput, SectionHeader, StatusDot, Chip

Custom Monaco theme (src/theme/monaco-theme.ts):
- typst-leaf-light: warm near-white background, restrained rainbow-free syntax
- Keywords teal, strings warm green, comments stone italic, most tokens ink

Component reworks:
- TopBar: Leaf icon, h-12, chip-based status, Button/IconButton primitives
- Sidebar: w-72, icon+label tabs with teal bottom border
- StatusBar: lucide GitBranch/ArrowUp/ArrowDown, chip-based status
- FileTree: lucide Plus/FolderPlus/Pencil/Trash2, teal active state
- GitPanel: lucide status icons, restored staged/unstaged bg tint
- Preview: RotateCw reload icon, chip status
- EmptyState: muted Leaf icon
- ToastHost: StatusDot + lucide X

Fixes:
- GitPanel staged/unstaged/untracked rows now have distinct bg tints
- Button defaults to type="button" to prevent accidental form submission
- Editor error fallback from red-400 to rose-600
- DESIGN.md: removed emoji from layout skeleton, fixed Modals/Monaco typo

Build: pnpm -r typecheck + pnpm build pass.
2026-07-03 13:34:47 +05:30

7.5 KiB

DESIGN.md — typst-leaf UI

Vision

"A fresh sheet of paper on a warm desk." Refined editorial-paper aesthetic with a deep teal accent and warm cream neutrals. The app chrome (sidebar, topbar, statusbar) is a warm cream; editor and preview surfaces are a brighter near-white — so reading and writing happen on a sheet of paper that lifts off the desk.

Brand

  • Name: typst-leaf — warm, organic, paper-and-ink.
  • Mark: A teal Leaf icon (lucide) beside the wordmark.
  • Personality: Quiet, considered, a serious editor for prose, papers, and beautiful documents. Like a focused notebook, not a dashboard.

Palette (Tailwind v4 @theme)

Custom tokens in src/index.css:

Token Value Use
canvas #faf8f4 App chrome (sidebar, topbar, statusbar, app bg)
surface #fdfdfb Editor, preview, raised panels, inputs
surface-hover #f3f1ec Hover backgrounds
ink #1c1917 Primary body text
ink-muted #78716c Secondary text, meta
ink-subtle #a8a29e Placeholders, subtle meta
line #e7e5e4 Hairline borders, dividers
line-strong #d6d3d1 Input borders
Token Value Use
teal-50 #f0f9f8 Active row tints, soft accents
teal-100 #d5edea Focus ring, highlights
teal-500 #14b8a6 Status dots, focus border
teal-600 #0f766e Primary actions, active text
teal-700 #115e59 Primary hover

Functional: amber-* (warnings, dirty, behind), rose-* (errors, destructive). Monaco defaults (zinc-* border, body text) are left as-is.

No dark classes. Tailwind v4 CSS-first only.

Typography

  • UI: font-sans → Inter Variable (via @fontsource-variable/inter).
  • Mono: font-mono → JetBrains Mono Variable (via @fontsource-variable/jetbrains-mono).
  • Monaco editor also uses JetBrains Mono for consistency.
  • Brand wordmark: font-semibold tracking-tight.
  • Section headers: text-[11px] uppercase tracking-wider text-ink-subtle.
  • File paths: font-mono text-ink-muted.
  • Meta: text-xs text-ink-subtle.

Icons

lucide-react, tree-shakeable. Wrapped via Icon component with size-4 stroke-[1.5] text-current. Curated set: Leaf, Plus, FolderPlus, Pencil, Trash2, ChevronDown, ChevronRight, X, Settings, RotateCw, GitBranch, ArrowUp, ArrowDown, Files, GitGraph.

Layout Skeleton

┌──────────────────────────────────────────────────────────────────────┐
│ TopBar: # typst-leaf · project · main.typ  Save  LSP  PRV  @    │
├──────────┬───────────────────────────────────────────────────────────┤
│ Sidebar  │                                                           │
│  Files   │                                                           │
│  ─────── │                     Monaco Editor                          │
│  ▣ main  │                    (typst-leaf-light theme)               │
│  ▣ lib/  │                                                           │
│  Git     │                                                           │
│  Settings├─────────────────────────────────────┬─────────────────────┤
│          │           Editor (resizable)        │      Preview       │
│          │                                     │     (iframe)       │
│          │                                     │                    │
└──────────┴─────────────────────────────────────┴─────────────────────┘
│ StatusBar: main · clean · LSP · Preview · vim · saving…                   │
└──────────────────────────────────────────────────────────────────────┘

Component Specs

TopBar

  • h-12, bg-canvas, border-b border-line.
  • Left: Leaf icon (teal-600, size-5), "typst-leaf" (semibold, tracking-tight), middot divider, project name, / divider, file path (font-mono text-ink-subtle).
  • Right: LSP/Preview Chip (hidden when no file), Button primary Save, IconButton Settings.
  • When no project: text-centered "Select a project to begin".

Sidebar

  • w-72, bg-canvas, border-r border-line.
  • ProjectPicker at top with border-b border-line.
  • Three icon+label tabs (Files, Git, Settings): active = teal text + 2px teal bottom border on surface; inactive = ink-muted.
  • Section headers: uppercase tracking-wider text-ink-subtle text-[11px].

StatusBar

  • h-7, bg-canvas, border-t border-line.
  • GitBranch icon + branch name, clean/dirty, ahead/behind with arrows.
  • LSP/Preview Chip.
  • Vim indicator and saving indicator.

ResizableSplit

  • flex h-full min-h-0 w-full flex-1.
  • Divider: w-1 bg-line hover:bg-teal-400, cursor-col-resize, transition-colors.
  • Panels: min-w-[280px] overflow-hidden.

EmptyState

  • Centered with muted Leaf icon, message, and optional hint.
  • text-ink-subtle.

ToastHost

  • Fixed bottom-right, rounded-lg shadow-sm.
  • StatusDot + message + lucide X close.
  • Kinds: teal (success), rose (error), neutral (info).

Preview

  • bg-surface, toolbar with "Preview" label, status Chip, RotateCw reload button.
  • Content: full-height iframe or centered placeholder text.

Editor

  • h-full flex flex-col min-h-0. Toolbar: mono file path, Vim toggle, vim status.
  • Monaco with custom typst-leaf-light theme (warm near-white background, restrained rainbow-free syntax palette).

FileTree

  • Nested tree with hover:bg-surface-hover rows, active file bg-teal-50 text-teal-700.
  • Inline rename/create inputs with border-teal-400.
  • Hover actions with lucide icons (Plus, FolderPlus, Pencil, Trash2).
  • Dirty files marked with amber dot.

GitPanel

  • Section header with branch name, ahead/behind arrows.
  • Changed files with lucide status icons (Plus/Pencil/X/HelpCircle).
  • Button primary Commit, Button secondary Push/Pull with ArrowUp/ArrowDown icons.
  • Collapsible Log with chevron.

SettingsPanel

  • "Git Identity" section.
  • TextInputs for name/email, Button primary Save, Button secondary Clear.

States

  • No project: large empty state in main area; sidebar shows project list.
  • Connecting: amber pulse dot on LSP/Preview chips.
  • Error: rose-600 text in error banner and toasts.
  • Save error: rose toast + dirty marker on file name.
  • Git dirty: amber dot on file in tree.

Motion

  • Hover/focus: transition-colors duration-150.
  • Button press: active:scale-[0.98] on primary buttons.
  • Toast: none (instant show/hide).
  • Connecting dots: animate-pulse.

Accessibility

  • Visible focus rings: focus-visible:ring-2 focus-visible:ring-teal-100 focus-visible:ring-offset-2.
  • All interactive controls keyboard-reachable.
  • State communicated by text + color, never color alone.

Don'ts

  • No gradients on chrome.
  • No shadows on panels (only on toasts).
  • No animated chrome unless real state change.
  • No emoji in product UI — icons only from lucide.
  • No dark mode.