UI Design - ArunPrakashG/native-launcher GitHub Wiki

UI Design

Native Launcher features a modern, polished UI with fully rounded elements, smooth animations, and a consistent design language inspired by contemporary launchers like Raycast, Albert, and macOS Spotlight.

Design Philosophy

Core Principles

  1. Modern & Minimal - Clean interface without clutter
  2. Fast & Responsive - Animations never block, 60+ fps target
  3. Keyboard-First - Visual feedback for all keyboard actions
  4. Consistent - Unified design language across all elements

Visual Identity

  • Charcoal Background (#1C1C1E) - Dark, modern base
  • Coral Accent (#FF6363) - Warm, energetic highlight
  • Rounded Everything - No sharp corners, modern feel
  • Subtle Animations - Smooth transitions without distraction

Color System

CSS Variables

/* Primary Colors */
--nl-bg-primary: #1c1c1e; /* Main background */
--nl-bg-secondary: #2c2c2e; /* Secondary surfaces */
--nl-bg-tertiary: #3a3a3c; /* Tertiary surfaces */

/* Accent */
--nl-primary: #ff6363; /* Coral accent */
--nl-primary-hover: #ff7a7a; /* Lighter coral */

/* Text */
--nl-text-primary: #ebebf5; /* Primary text (off-white) */
--nl-text-secondary: #ebebf599; /* Secondary text (60% opacity) */
--nl-text-tertiary: #ebebf566; /* Tertiary text (40% opacity) */
--nl-text-quaternary: #ebebf533; /* Quaternary text (20% opacity) */

/* Borders */
--nl-border: #48484a; /* Subtle borders */
--nl-surface-secondary: #2c2c2e; /* Surface backgrounds */
--nl-surface-tertiary: #3a3a3c; /* Elevated surfaces */

Usage Guidelines

  • Primary text: App names, titles, main content
  • Secondary text: Descriptions, subtitles, metadata
  • Tertiary text: Hints, supplementary info
  • Quaternary text: Disabled states, placeholders
  • Coral accent: Selection, focus, call-to-action

Border Radius System

Progressive rounding scale for consistent hierarchy:

Element Border Radius Purpose
Window 20px Largest container, most pronounced
Search Entry 16px Primary input, prominent
Search Footer 16px Footer sections, consistent with entry
List Container 16px Major content areas
List Rows 14px Interactive items
Plugin Warning 12px Notifications, alerts
Icons 12px Small rounded elements
Scrollbar 12px UI controls
Keyboard Hints 8px Smallest elements

Design Logic

  • Large elements (20px): Window, main containers
  • Medium elements (14-16px): Interactive areas, inputs
  • Small elements (12px): Icons, controls, badges
  • Tiny elements (8px): Pills, hints, tags

Animation System

Timing Variables

--nl-animation-fast: 0.15s; /* Hover, quick feedback */
--nl-animation-normal: 0.25s; /* Default transitions */
--nl-animation-slow: 0.35s; /* Window appearance */
--nl-easing: cubic-bezier(0.4, 0, 0.2, 1); /* Material Design easing */

Window Appearance

Animation: Fade in + scale up + slide down

@keyframes windowAppear {
  from {
    opacity: 0;
    transform: scale(0.95) translateY(-20px);
  }
  to {
    opacity: 1;
    transform: scale(1) translateY(0);
  }
}

Duration: 0.35s (slow, dramatic entrance)

List Entry Animation

Animation: Slide in from left + scale up + fade in

@keyframes rowSlideIn {
  from {
    opacity: 0;
    transform: translateX(-10px) scale(0.98);
  }
  to {
    opacity: 1;
    transform: translateX(0) scale(1);
  }
}

Staggered Timing: First 10 items cascade with 0.02s delay increments

listbox row:nth-child(1) {
  animation-delay: 0s;
}
listbox row:nth-child(2) {
  animation-delay: 0.02s;
}
listbox row:nth-child(3) {
  animation-delay: 0.04s;
}
/* ... up to 10 */

Effect: Smooth cascade animation when results appear

List Exit Animation

Animation: Slide out to right + scale down + fade out

@keyframes rowSlideOut {
  from {
    opacity: 1;
    transform: translateX(0) scale(1);
  }
  to {
    opacity: 0;
    transform: translateX(10px) scale(0.98);
  }
}

Duration: 0.15s (fast exit, no delay)

Hover Effects

List Row Hover:

listbox row:hover {
  transform: scale(1.01);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

Icon Hover (parent row hovered):

listbox row:hover image {
  transform: scale(1.05) rotate(2deg);
}

Entry Focus:

entry:focus {
  transform: scale(1.01);
  box-shadow: 0 0 0 4px rgba(255, 99, 99, 0.2);
}

Selection Effects

List Row Selected:

listbox row:selected {
  transform: scale(1.02);
  background: linear-gradient(
    90deg,
    rgba(255, 99, 99, 0.15),
    rgba(255, 99, 99, 0.05)
  );
  box-shadow: 0 0 0 2px rgba(255, 99, 99, 0.3), 0 8px 16px rgba(0, 0, 0, 0.2);
}

Icon Selected (parent row selected):

listbox row:selected image {
  transform: scale(1.05) rotate(2deg);
  filter: brightness(1.1);
}

Text Glow (selected row text):

listbox row:selected .app-name {
  text-shadow: 0 0 8px rgba(255, 99, 99, 0.3);
}

Typography

Font Stack

font-family: "SF Pro", "Inter", "Segoe UI", system-ui, sans-serif;

Fallback Order:

  1. SF Pro (macOS style)
  2. Inter (modern geometric)
  3. Segoe UI (Windows)
  4. system-ui (native system font)
  5. sans-serif (universal fallback)

Font Sizes

Element Size Weight Usage
App Name 15px 600 Primary titles
Generic Name 13px 400 Descriptions
File Path 12px 400 Technical info, paths
Footer Text 13px 500 Status, hints
Warning Text 12px 500 Alerts, notifications
Keyboard Hints 12px 500 Shortcut pills

Monospace Stack (for paths)

font-family: "JetBrains Mono", "Fira Code", "SF Mono", "Roboto Mono", monospace;

Used for: File paths, commands, technical data

Component Styles

Window

window {
  background: linear-gradient(180deg, #1c1c1e 0%, #18181a 100%);
  border-radius: 20px;
  border: 1px solid #48484a;
  box-shadow: 0 16px 48px rgba(0, 0, 0, 0.4);
  animation: windowAppear 0.35s cubic-bezier(0.4, 0, 0.2, 1);
}

Features:

  • Subtle gradient for depth
  • Large border radius (20px)
  • Dramatic shadow
  • Entrance animation

Search Entry

entry {
  background-color: #2c2c2e;
  border: 2px solid transparent;
  border-radius: 16px;
  padding: 16px 24px;
  margin: 16px;
  font-size: 16px;
  color: #ebebf5;
  transition: all 0.15s cubic-bezier(0.4, 0, 0.2, 1);
}

entry:focus {
  border-color: rgba(255, 99, 99, 0.4);
  background-color: #3a3a3c;
  transform: scale(1.01);
  box-shadow: 0 0 0 4px rgba(255, 99, 99, 0.2);
}

Features:

  • Large rounded corners (16px)
  • Generous padding (16px 24px)
  • Focus: Coral border + glow + scale
  • Smooth transition

List Rows

listbox row {
  background-color: transparent;
  border-radius: 14px;
  padding: 14px 20px;
  margin: 3px 12px;
  opacity: 0;
  transform: translateX(-10px) scale(0.98);
  animation: rowSlideIn 0.25s cubic-bezier(0.4, 0, 0.2, 1) forwards;
  transition: all 0.15s cubic-bezier(0.4, 0, 0.2, 1);
}

listbox row:hover {
  background-color: rgba(255, 255, 255, 0.05);
  transform: scale(1.01);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

listbox row:selected {
  background: linear-gradient(
    90deg,
    rgba(255, 99, 99, 0.15),
    rgba(255, 99, 99, 0.05)
  );
  transform: scale(1.02);
  box-shadow: 0 0 0 2px rgba(255, 99, 99, 0.3), 0 8px 16px rgba(0, 0, 0, 0.2);
}

Features:

  • Slide-in entrance animation
  • Staggered delays for cascade effect
  • Hover: Subtle scale + shadow
  • Selection: Coral gradient + glow + larger scale

Icons

.app-icon {
  border-radius: 12px;
  min-width: 48px;
  min-height: 48px;
  transition: transform 0.15s cubic-bezier(0.4, 0, 0.2, 1);
}

listbox row:hover .app-icon,
listbox row:selected .app-icon {
  transform: scale(1.05) rotate(2deg);
}

Features:

  • Rounded corners (12px)
  • Hover/select: Scale + slight rotation
  • Smooth transition

Pinned Overlay

Pinned apps display a coral star overlay on the top-right of their icon:

.pinned-star {
  color: var(--nl-primary);
  font-size: 14px;
  text-shadow: 0 0 4px rgba(0, 0, 0, 0.4);
}

listbox row:selected .pinned-star {
  color: #fff;
  text-shadow: 0 0 6px rgba(255, 99, 99, 0.35);
}

The overlay is implemented with GtkOverlay so the star stacks over the icon without shifting text.

Scrollbar

scrollbar slider {
  background: #ebebf533;
  border-radius: 12px;
  min-width: 6px;
  transition: all 0.15s ease;
}

scrollbar slider:hover {
  background: #ebebf566;
  min-width: 10px;
}

Features:

  • Minimal, subtle design
  • Expands on hover (6px → 10px)
  • Fully rounded (12px)

Desktop Actions (Inline)

listbox row box[margin-start="24"] {
  padding-left: 12px;
  border-left: 3px solid #ebebf533;
  border-radius: 0 8px 8px 0;
  transition: all 0.15s cubic-bezier(0.4, 0, 0.2, 1);
}

listbox row:selected box[margin-start="24"] {
  border-left-color: rgba(255, 255, 255, 0.9);
  border-left-width: 4px;
}

listbox row:hover box[margin-start="24"] {
  border-left-color: #ff6363;
  border-left-width: 4px;
}

Features:

  • 24px left indent
  • Coral left border
  • Thicker border on hover/select (3px → 4px)
  • Right-side rounded corners only

Accessibility

Contrast Ratios

All text meets WCAG AA standards:

  • Primary text (#EBEBF5 on #1C1C1E): 12.8:1 ✅
  • Secondary text (60% opacity): 7.7:1 ✅
  • Coral accent (#FF6363 on #1C1C1E): 5.2:1 ✅

Motion

Respecting reduced motion preferences (future):

@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

Performance Considerations

Animation Performance

  • Hardware acceleration: transform and opacity only
  • No layout thrashing: Avoid animating width, height, margin
  • 60fps target: All animations <16ms per frame
  • Minimal repaints: Use will-change sparingly

CSS Optimization

/* Good: GPU-accelerated */
transform: scale(1.02);
opacity: 0.5;

/* Bad: CPU-intensive */
width: 200px;
margin-left: 10px;

Animation Budget

  • Window appear: 35ms (acceptable, one-time)
  • List entry (10 items): 200ms total (acceptable)
  • Hover effects: 15ms (instant feel)

Theming Guide

Custom Themes

Users can override styles in ~/.config/native-launcher/custom.css:

/* Custom theme example: Blue accent */
:root {
  --nl-primary: #007aff;
  --nl-primary-hover: #0a84ff;
}

/* Larger text */
.app-name {
  font-size: 16px;
}

/* Sharper corners */
window {
  border-radius: 10px;
}

Load custom CSS in config.toml:

[ui]
custom_css = "~/.config/native-launcher/custom.css"

Design References

Inspiration drawn from:

References

See Also