Skip to content

Latest commit

 

History

History
426 lines (368 loc) · 24.3 KB

DESIGN.md

File metadata and controls

426 lines (368 loc) · 24.3 KB
name OpenGitDesktop
description Design system for OpenGitDesktop — a cross-platform desktop Git client with supervised AI assistance.
colors
midnight-base obsidian-panel coal-raised hover-overlay active-overlay primary-text secondary-text tertiary-text default-border focus-border command-blue command-blue-soft attention-orange attention-orange-soft success-green success-green-soft danger-red danger-red-soft danger-fill danger-fill-hover on-danger field-border diff-add-ink diff-hunk-ink diff-meta-ink diff-gutter-ink warning-amber warning-amber-soft action-surface action-ink
#0a0a0b
#131315
#1b1b1e
#ffffff0d
#479ffa14
#ffffff
#868f97
#999999
#ffffff14
#479ffa
#479ffa
#479ffa1f
#ffa16c
#ffa16c1a
#4ebe96
#4ebe961a
#e15c5c
#261b1b
#c24848
#ad3e3e
#ffffff
#ffffff57
#4ebe96
#479ffa
#999999
#858585
#f2b84b
#f2b84b1f
#e6e6e6
#000000
themeVariants
light dark-hc light-hc
midnight-base obsidian-panel coal-raised hover-overlay active-overlay primary-text secondary-text tertiary-text default-border focus-border command-blue command-blue-soft attention-orange attention-orange-soft success-green success-green-soft danger-red danger-red-soft danger-fill danger-fill-hover on-danger field-border diff-add-ink diff-hunk-ink diff-meta-ink diff-gutter-ink warning-amber warning-amber-soft action-surface action-ink
#f6f5f3
#ffffff
#ececea
#00000009
#1f6fe014
#14171a
#5b6570
#69727d
#00000014
#1f6fe0
#1f6fe0
#1f6fe014
#b5590f
#b5590f14
#157a55
#157a5514
#c22b2b
#fbe9e9
#c22b2b
#a82424
#ffffff
#0000006b
#136f4d
#1b5fc1
#646d78
#646d78
#8a5a00
#8a5a0014
#262b30
#ffffff
midnight-base obsidian-panel coal-raised hover-overlay active-overlay primary-text secondary-text tertiary-text default-border focus-border command-blue command-blue-soft attention-orange attention-orange-soft success-green success-green-soft danger-red danger-red-soft danger-fill danger-fill-hover on-danger field-border diff-add-ink diff-hunk-ink diff-meta-ink diff-gutter-ink warning-amber warning-amber-soft action-surface action-ink
#000000
#000000
#0d0d0d
#ffffff26
#7fc4ff26
#ffffff
#e6e6e6
#cfcfcf
#ffffff66
#7fc4ff
#7fc4ff
#7fc4ff33
#ffb366
#ffb36633
#5be8ac
#5be8ac33
#ff6b6b
#3a1414
#ff6b6b
#ff8585
#000000
#ffffff66
#5be8ac
#7fc4ff
#cfcfcf
#cfcfcf
#ffd166
#ffd16633
#f0f0f0
#000000
midnight-base obsidian-panel coal-raised hover-overlay active-overlay primary-text secondary-text tertiary-text default-border focus-border command-blue command-blue-soft attention-orange attention-orange-soft success-green success-green-soft danger-red danger-red-soft danger-fill danger-fill-hover on-danger field-border diff-add-ink diff-hunk-ink diff-meta-ink diff-gutter-ink warning-amber warning-amber-soft action-surface action-ink
#ffffff
#ffffff
#f2f2f2
#00000026
#0050b326
#000000
#1a1a1a
#333333
#00000066
#0050b3
#0050b3
#0050b31a
#8a3d00
#8a3d001a
#0b6b46
#0b6b461a
#a30000
#f7dede
#a30000
#8a0000
#ffffff
#0000006b
#0b6b46
#0050b3
#333333
#333333
#7a4b00
#7a4b001a
#202020
#ffffff
typography
display headline metric title body caption meta label
fontFamily fontSize fontWeight lineHeight letterSpacing
calibre, Inter, ui-sans-serif, system-ui, -apple-system, sans-serif
34px
600
0.95
-0.04em
fontFamily fontSize fontWeight lineHeight letterSpacing
calibre, Inter, ui-sans-serif, system-ui, -apple-system, sans-serif
22px
600
1.2
-0.02em
fontFamily fontSize fontWeight lineHeight letterSpacing
calibre, Inter, ui-sans-serif, system-ui, -apple-system, sans-serif
18px
600
1.2
-0.02em
fontFamily fontSize fontWeight lineHeight letterSpacing
calibre, Inter, ui-sans-serif, system-ui, -apple-system, sans-serif
16px
600
1.3
-0.02em
fontFamily fontSize fontWeight lineHeight letterSpacing
calibre, Inter, ui-sans-serif, system-ui, -apple-system, sans-serif
14px
400
1.5
normal
fontFamily fontSize fontWeight lineHeight letterSpacing
calibre, Inter, ui-sans-serif, system-ui, -apple-system, sans-serif
12px
400
1.45
normal
fontFamily fontSize letterSpacing
calibre, Inter, ui-sans-serif, system-ui, -apple-system, sans-serif
11px
normal
fontFamily fontSize fontWeight lineHeight letterSpacing
calibre, Inter, ui-sans-serif, system-ui, -apple-system, sans-serif
10px
600
1.5
0.08em
rounded
sm md lg button pill
6px
10px
16px
8px
99px
spacing
xxs xs sm md lg xl
4px
8px
12px
16px
20px
24px
components
button-primary button-primary-hover button-secondary button-danger input-default card-default chip-command
backgroundColor textColor typography rounded padding height
{colors.action-surface}
{colors.action-ink}
{typography.body}
{rounded.button}
7px 16px
34px
backgroundColor textColor
{colors.primary-text}
{colors.action-ink}
backgroundColor textColor typography rounded padding height
{colors.midnight-base}
{colors.primary-text}
{typography.body}
{rounded.button}
7px 16px
34px
backgroundColor textColor typography rounded padding height
{colors.danger-fill}
{colors.on-danger}
{typography.body}
{rounded.button}
7px 16px
34px
backgroundColor textColor typography rounded padding
{colors.midnight-base}
{colors.primary-text}
{typography.body}
{rounded.sm}
10px 12px
backgroundColor textColor rounded padding
{colors.obsidian-panel}
{colors.secondary-text}
{rounded.lg}
20px
backgroundColor textColor typography rounded padding
{colors.command-blue-soft}
{colors.command-blue}
{typography.label}
{rounded.pill}
2px 10px

Design System: OpenGitDesktop

1. Overview

Creative North Star: "The Local Workbench"

OpenGitDesktop is a dense, calm desktop Git workbench. Near-black surfaces keep attention on the repository state — changes, diffs, branches, conflicts, and the next commit — while chrome stays quiet. The visual system is controlled intensity: clear when something needs action (conflicts, errors, destructive confirms), restrained everywhere else.

The interface is a product workspace, not a spectacle. Compact controls, exact labels, restrained interaction color, and explicit semantic states support fast daily Git workflows. Navigation and chrome recede; success, danger, warnings, and primary actions remain unmistakable. The system rejects glossy generic SaaS marketing, neon decoration, and undifferentiated admin CRUD chrome.

Key Characteristics:

  • Near-black tonal layers with crisp content contrast.
  • Compact, decisive controls built for repeated operational use.
  • Color reserved for interaction and semantic state.
  • Dense layouts organized by hierarchy rather than decoration.
  • Structure that preserves the primary task when the window is narrowed.

2. Colors

The palette is restrained at rest and categorical in motion: neutrals carry the workspace while operational colors identify action, attention, success, danger, and warning.

Primary

  • Command Blue (#479ffa): marks focus, active navigation, selected states, links, and informational feedback. It is an interaction signal, never ambient decoration.

Secondary

  • Attention Orange (#ffa16c): marks setup emphasis and information that deserves review but is not yet a warning or failure.

Tertiary

  • Success Green (#4ebe96): communicates successful execution, additions in diffs, and healthy state.
  • Danger Red (#e15c5c): communicates destructive action, failed state, deletions in diffs, and conditions requiring intervention.
  • Warning Amber (#f2b84b): communicates caution, merge conflicts, and unresolved operational risk.

Neutral

  • Midnight Base (#0a0a0b): the application canvas and recessed control background.
  • Obsidian Panel (#131315): the default panel, menu, and card surface.
  • Coal Raised (#1b1b1e): the raised layer for selected blocks and secondary surfaces.
  • Primary Text (#ffffff): headings, key values, and active control content.
  • Secondary Text (#868f97): body copy, descriptions, and supporting data.
  • Tertiary Text (#999999): compact metadata and placeholders where contrast remains compliant.
  • Action Surface (#e6e6e6): the default primary button surface with black action ink.

Named Rules

The Operational Color Rule. Chromatic color always means action or state. If a hue does not help the operator decide, remove it.

The Data-Viz Exception. Charts on the Dashboard are the one place hue encodes identity (a language, a contributor) instead of action or state. They use their own --viz-1…8 categorical set and a --viz-seq-1…5 blue ramp (defined in global.css), validated for colour-vision deficiency against the real panel surfaces, separately stepped for dark and light. Chart text stays in text tokens; every coloured mark has a visible text label beside it.

The Activity Sky Exception. The Messages screen is the one operational surface allowed atmosphere, by explicit product decision: the account's last 30 days are drawn as a night sky, and that sky is a real spatial canvas plotting real data. Inside .sky it may use soft radial washes of Command Blue and Warning Amber, a bottom fade into Midnight Base, decorative dust, a drop-shadow glow on star marks, and a glint on new stars. Amber here encodes identity (a GitHub star), not caution; --sky-star replaces Warning Amber in the light theme, whose text-grade value reads brown as a mark. The invitation card just below (.inbox-invite) may carry a soft tint and a colored offset shadow, because it is the screen's one decision. High-contrast themes drop the washes, dust, glints, glow, card tint and colored shadow; prefers-reduced-motion stops all of the movement. This exception does not extend to any other screen.

The Red Means Danger Rule. Danger Red is reserved for destructive actions, failures, and intervention. It is forbidden as decorative emphasis.

The Contrast Before Atmosphere Rule. Readability wins over subtlety. Muted text and placeholders must meet WCAG 2.2 AA against their actual surface, in every theme variant, not only the dark default.

Theme Variants

The dark palette above (colors:) is the default and the reference identity — every other variant is that same role set recomposed for a different canvas, never a mechanical color inversion:

  • Light: a warm near-white canvas (#f6f5f3, not sterile white) replaces Midnight Base; every semantic hue (Command Blue, Success Green, Danger Red, Warning Amber, Attention Orange) is deepened enough to still read as text at WCAG AA on that canvas — the same hue family, recomposed, never the raw dark-theme value lightened. The primary button flips from a light "ink" surface to a dark one (#262b30) so it stays the single strongest tonal object in the room, matching what Action Surface already does in the dark theme.
  • Dark, high contrast and Light, high contrast: pure black or pure white canvas. Every role that depended on a subtle tonal step (panel vs. raised) or a low-alpha overlay (borders, hover, active) instead depends on an always-visible border or a brightened/deepened, more saturated hue — subtlety is exactly what a high-contrast user cannot rely on. Text and semantic colors clear 6.5:1–14:1 against their canvas, well past the 4.5:1 floor the other two variants target.

Full token values live in themeVariants in this file's frontmatter, and are mirrored as CSS custom-property overrides per data-theme value in GitWeb/src/renderer/src/styles/global.css. Selecting a variant (from prefers-color-scheme, prefers-contrast, or a manual override) is application logic, not a design decision this file makes.

The Recomposed, Not Inverted Rule. A new theme variant may never be produced by mechanically inverting or lightening/darkening the dark theme's raw values. Compose each surface, text, and semantic role independently against its own canvas, verify contrast, and only then compare against the sibling variants for family resemblance.

3. Typography

Display Font: calibre with Inter and system sans-serif fallbacks
Body Font: calibre with Inter and system sans-serif fallbacks
Mono Font: JetBrains Mono for diffs, hashes, and genuine code content only

Character: One technical sans family carries the product chrome. Hierarchy comes from size, weight, and spacing rather than competing typefaces. Monospace is reserved for repository content, never UI labels.

Hierarchy

  • Display (600, 34px, 0.95): reserved for rare hero statements (e.g. empty first-run). Tracking must never tighten beyond -0.04em.
  • Headline (600, 22px, 1.2): page titles and major workflow headings.
  • Metric (600, 18px, 1.2): compact counts and values that must lead within a block.
  • Title (600, 16px, 1.3): panel titles, dialog titles, and high-priority row labels.
  • Body (400, 14px, 1.5): instructions, descriptions, controls, and operational copy; prose is capped near 70ch.
  • Caption (400, 12px, 1.45): secondary metadata on pointer-precise layouts.
  • Meta (11px, inherits line-height): dense metadata inside compact rows — ref chips, counts, timestamps, branch tokens. Token --text-meta / text-meta; never an arbitrary text-[11px].
  • Label (600, 10px, 0.08em, uppercase when categorical): section headers and short state labels only.

Named Rules

The One-Family Rule. Product labels, buttons, data, and headings use the same sans family. Display fonts are prohibited in operational UI.

The Tabular Data Rule. Counts, hashes (when aligned), and timestamps use tabular numerals whenever columns or repeated values must align.

The Uppercase Budget Rule. Uppercase tracking is reserved for compact categorical labels and section headers; it must not become a decorative scaffold.

4. Elevation

OpenGitDesktop uses structural layering. Midnight Base, Obsidian Panel, and Coal Raised establish most depth; subtle borders separate adjacent surfaces. Shadows belong to floating menus, dialogs, toasts, and genuine overlays. Ambient card shadow must not be the default treatment for every panel.

Shadow Vocabulary

  • Floating Surface (rgba(0, 0, 0, 0.8) 0 12px 44px -12px): menus, dialogs, toasts, and overlays that must separate from the application shell.
  • Subtle Edge (rgba(0, 0, 0, 0.85) 0 1px 0): compact notification surfaces or controls that need a single lower edge.
  • Command Glow (0 0 20px rgba(71, 159, 250, 0.06)): rare informational emphasis around an active system surface, never routine card decoration.
  • Raised (--shadow-raised: a 1px inset top highlight plus 0 1px 2px drop): cards, the header status cluster, and tile controls. It reads as a machined edge, not a float, so it does not break the No Ghost Card Rule. Disabled in high-contrast variants.

Motion

  • View enter: switching tabs brings the incoming view up 6px with a 3px de-blur over 280ms (expo ease-out). It uses backwards fill only, so no transform or filter lingers to trap position: fixed menus.
  • List selection: rows mark hover and selection with a short rounded accent pill on the leading edge that grows from the row's middle (--row-accent recolors it; conflicts use Warning Amber).
  • Tab indicator: the active tab's underline grows from its center.
  • Assistant standby: the empty-chat emblem breathes a soft Command Blue ring. Outside the Activity Sky, it is the only idle loop in the app.
  • Activity Sky: on Messages, the graph line draws itself once on entry, and a few dust points, new stars and the "now" marker keep moving quietly. Anything that loops lives on its own layer outside the SVG, so it never repaints the sky.
  • All of it collapses under prefers-reduced-motion.

Named Rules

The Structural Layering Rule. Use tonal surface changes and borders first. Add shadow only when an element physically floats above its context.

The No Ghost Card Rule. Never pair a one-pixel border with a wide decorative drop shadow on ordinary cards or buttons.

Scrollbars

Every scrollable surface — vertical and horizontal — uses the application scrollbar, never the operating system default.

  • Thumb (rgba(255, 255, 255, 0.16)): visible against Obsidian Panel without competing with content.
  • Thumb, hover (rgba(255, 255, 255, 0.32)): confirms the bar is grabbable.
  • Track: always transparent — the panel behind it supplies the surface.
  • Thickness: 10px with a 2px transparent inset (background-clip: padding-box). Firefox gets the same result through scrollbar-width: thin.

Declared once globally in GitWeb/src/renderer/src/styles/global.css under @layer base. Scrollable areas inherit it; they must not restyle it locally.

The Application Scrollbar Rule. Scrollable surfaces use the application scrollbar in both axes. Never ship a default OS scrollbar inside a panel, and never hide a scrollbar that still scrolls.

The Far-Right Vertical Scrollbar Rule. A page-level or pane-level vertical scrollbar must sit on the far right edge of the surface that owns the scroll — the window, main, or the split pane — never on a centered column. Center the content inside a full-width scroller (h-full overflow-y-auto wrapping mx-auto max-w-*). Do not put overflow-y-auto on the max-w-* wrapper itself; that parks the thumb in the middle of the window. Nested widget scrollers (combobox lists, modal repo lists, the About release-notes card) stay on their own box.

5. Components

Components are compact and decisive. Every control must expose a familiar affordance and a complete set of default, hover, focus, active, disabled, loading, and error states where applicable.

Buttons

  • Shape: primary, secondary and semantic actions use the button radius (8px) — a softened rectangle, never the full pill, which stays reserved for chips, badges, switches and progress tracks. Compact icon and ghost controls use the small or medium radius (6px to 10px). A split button (action + attached menu trigger) squares the two inner corners where the halves meet and keeps the button radius on the outer ones.
  • Primary: Action Surface with black text, 7px 16px padding, and a 34px default height.
  • Hover / Focus: hover increases surface contrast; keyboard focus is a two-pixel solid Focus Border (Command Blue) outline, which must hold 3:1 against every surface it lands on — never a translucent ring. State transitions complete in 100ms to 150ms.
  • Secondary / Ghost / Semantic: secondary remains transparent with a quiet border; ghost controls recede to secondary text; danger variants are reserved for destructive actions and fill with Danger Fill under On Danger text (≥4.5:1 in every theme); Danger Red stays the text/icon hue.

Chips

  • Style: compact pill, soft semantic background, matching semantic text, and a low-contrast full border.
  • State: blue identifies selection or information, green success, red danger, orange attention, amber warning, and neutral metadata. Color must be reinforced by text or iconography.

Cards / Containers

  • Corner Style: gently rounded (16px maximum for cards; 10px for embedded blocks).
  • Background: Obsidian Panel on Midnight Base; Coal Raised only for nested emphasis without creating a card inside a card.
  • Shadow Strategy: flat by default; use the Floating Surface shadow only for true overlays.
  • Border: one-pixel Default Border separates panels where tonal contrast is insufficient.
  • Internal Padding: 16px to 20px; dense rows use 8px to 12px vertical rhythm.

Inputs / Fields

  • Style: Midnight Base, Primary Text, a one-pixel Field Border (3:1 against both the fill and the surrounding panel, so an empty field is findable at rest), 6px radius, and 10px 12px padding. Hover strengthens the edge to half-strength Primary Text.
  • Focus: Command Blue border with a three-pixel Command Blue Soft ring.
  • Error / Disabled: Danger Red communicates invalid state with adjacent text; disabled controls remain legible, preserve their label, and reduce opacity without disappearing.

Navigation

Desktop navigation is a compact top tab strip with labels — Changes, History, Stash, Pull Requests, and Settings. The active route uses Primary Text with a Command Blue underline. Hover reveals affordance without introducing new color. Repo, branch, and sync share one status cluster in the header; About lives in Settings, not as a competing header icon.

Switches and Floating Menus

Switches use a 42px by 24px track with an 18px thumb and explicit text labels. Comboboxes and row-action menus use Obsidian Panel with a 10px radius and escape scroll-container clipping. Floating surfaces must manage keyboard focus.

6. Do's and Don'ts

Do:

  • Do surface blocking Git state (conflicts, errors, ahead/behind) before secondary chrome.
  • Do use Command Blue only for interaction, focus, selection, and information.
  • Do use Success Green, Danger Red, and Warning Amber with text or icons so state never depends on hue alone.
  • Do use Midnight Base, Obsidian Panel, and Coal Raised to create structural depth before adding shadow.
  • Do keep ordinary cards at or below the canonical 16px radius and embedded blocks at 10px or below.
  • Do preserve complete keyboard operation, visible focus, reduced-motion alternatives, and WCAG 2.2 AA contrast.
  • Do let scrollable areas inherit the global application scrollbar, in both axes.
  • Do put page or pane scroll on a full-width container so the vertical thumb rides the far right edge; center content inside that scroller.
  • Do require explicit confirmation for destructive Git actions (discard, abort merge, drop stash, pop stash, merge or close a pull request). Danger confirms focus Cancel, not the destructive button.

Don't:

  • Don't turn OpenGitDesktop into glossy generic SaaS marketing with decorative gradients, hero-metric templates, or glass cards. The Activity Sky Exception is the only allowance, and only on Messages.
  • Don't use neon glows or speculative hype aesthetics. The restrained star glow inside the Activity Sky is the only exception.
  • Don't reduce the product to an undifferentiated CRUD admin panel; keep the daily Git path (changes → diff → commit) primary.
  • Don't compete with that path using equal-weight header cards or icon-only Settings/About buttons; Settings is a labeled tab, About lives inside it.
  • Don't use decorative grid backgrounds unless the surface is an actual charting or spatial canvas.
  • Don't use gradient text, colored side-stripe borders thicker than the list-row accent system, nested cards, or identical card grids as default structure.
  • Don't use 24px, 28px, or larger card radii; those values are implementation drift, not part of this system.
  • Don't apply the Floating Surface shadow to ordinary bordered cards or buttons.
  • Don't leave the default OS scrollbar on any scrollable surface, restyle scrollbars per component, or hide a bar on content that still scrolls.
  • Don't put overflow-y-auto on a centered max-w-* column; the vertical bar must not float in the middle of the window.