Modularity-Lib Style Guide

Comprehensive design system extracted from the modularity-lib — the reference for "that vibe" when building new UI in this codebase.

Modularity-Lib Style Guide

TL;DR for agents: When the user says "make it look like the modularity lib", "that vibe", or "similar design", they mean: deep dark purple/navy background, purple-to-blue gradient accents, translucent glassmorphism cards, subtle radial ambient glows, clean white typography, and smooth micro-interactions.


The Design in One Sentence

A dark-mode-first, glassmorphism-heavy UI built on a deep navy/purple base, with purple-to-blue gradient accents, translucent frosted-glass surfaces, and smooth hover micro-interactions — elegant, spacious, and modern.


Two Modes: Know Which One You're Building

The modularity-lib ships two complementary visual modes depending on context:

Mode Where Used Base Surface Feel
Dark Dashboard modularity-dashboard, module-card, module-workbench Deep navy #0f0f23 Rich, bold, spacious
Light Builder ai-builder Soft white/lavender Clean, airy, focused

Both use the same accent color system — only the surface changes. Default to Dark Dashboard unless explicitly asked for a light variant.


Color System

Primary Accent Gradients

These are the signature colors. Use them for CTAs, icons, active states, and highlights.

// PRIMARY — Purple to Blue (most common)
linear-gradient(135deg, #7c3aed, #3b82f6)

// AI / VIBE — Indigo to Violet (for AI features, brand moments)
linear-gradient(135deg, #6366f1, #a855f7)

// VIVID VIBE — Full spectrum (badges, hero moments)
linear-gradient(135deg, #6366f1 0%, #a855f7 50%, #ec4899 100%)

// HEADER ACCENT LINE (ultra-thin top border highlight)
linear-gradient(90deg, #6366f1 0%, #764ba2 50%, #f093fb 100%)

Semantic Colors

// Success
$color-success:       #10b981;
$color-success-light: #34d399;
$color-success-dim:   rgba(16, 185, 129, 0.15);

// Warning
$color-warning:       #f59e0b;
$color-warning-light: #fbbf24;
$color-warning-dim:   rgba(251, 191, 36, 0.15);

// Danger / Error
$color-danger:        #ef4444;
$color-danger-light:  #f87171;
$color-danger-dim:    rgba(248, 113, 113, 0.15);

// Info / Accent blue
$color-info:          #3b82f6;
$color-info-light:    #60a5fa;

// Favorite / Gold
$color-gold:          #fbbf24;

Dark Mode Surface Palette

// Page backgrounds
$bg-page:       linear-gradient(135deg, #0f0f23 0%, #1a1a3e 50%, #0d1421 100%);
$bg-ambient:    radial-gradient(ellipse at 20% 30%, rgba(124, 58, 237, 0.1), transparent 50%),
                radial-gradient(ellipse at 80% 70%, rgba(59, 130, 246, 0.08), transparent 50%);

// Surface tiers (glass cards, panels)
$surface-0:     rgba(255, 255, 255, 0.03);   // hero/hero-like panels
$surface-1:     rgba(255, 255, 255, 0.04);   // default cards
$surface-2:     rgba(255, 255, 255, 0.06);   // hovered cards
$surface-3:     rgba(255, 255, 255, 0.08);   // active/focused elements

// SCSS variable equivalents (module-workbench)
$surface:         #1a1a2e;
$surface-light:   #252542;
$surface-lighter: #2d2d4a;
$border:          #3d3d5c;

Text Hierarchy

$text-primary:     #ffffff;
$text-secondary:   rgba(255, 255, 255, 0.6);
$text-tertiary:    rgba(255, 255, 255, 0.5);
$text-quaternary:  rgba(255, 255, 255, 0.35);
$text-muted:       #94a3b8;      // workbench variant
$text-body:        #e2e8f0;      // workbench variant

Border / Divider

$border-subtle:   rgba(255, 255, 255, 0.06);
$border-default:  rgba(255, 255, 255, 0.08);
$border-medium:   rgba(255, 255, 255, 0.10);
$border-strong:   rgba(255, 255, 255, 0.15);
$border-accent:   rgba(124, 58, 237, 0.3);   // purple accent border
$border-accent-h: rgba(124, 58, 237, 0.4);   // hovered accent

Background Pattern

Every full-page view uses this layered background — a dark gradient base with soft ambient radial glows.

:host {
  display: block;
  min-height: 100vh;
  background: linear-gradient(135deg, #0f0f23 0%, #1a1a3e 50%, #0d1421 100%);

  // Ambient glow layer (fixed, not scrolling)
  &::before {
    content: '';
    position: fixed;
    inset: 0;
    background:
      radial-gradient(ellipse at 20% 30%, rgba(124, 58, 237, 0.10) 0%, transparent 50%),
      radial-gradient(ellipse at 80% 70%, rgba(59, 130, 246, 0.08) 0%, transparent 50%);
    pointer-events: none;
    z-index: 0;
  }
}

Rule: All direct children of the page host must have position: relative; z-index: 1 to render above this background layer.


Glassmorphism Card System

The cornerstone of the design. Cards are translucent frosted panels.

Default Card

.glass-card {
  background: rgba(255, 255, 255, 0.04);
  backdrop-filter: blur(12px);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 16px;
  transition: all 0.2s ease;

  &:hover {
    background: rgba(255, 255, 255, 0.06);
    border-color: rgba(124, 58, 237, 0.3);
    transform: translateY(-2px);
  }
}

Hero / Large Panel

.hero-panel {
  background: rgba(255, 255, 255, 0.03);
  backdrop-filter: blur(20px);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 20px;
  padding: 32px;
}

Card Back / Dark Variant

.card-back {
  background: linear-gradient(145deg, rgba(30, 20, 50, 0.98), rgba(40, 25, 70, 0.95));
  border-color: rgba(124, 58, 237, 0.3);
}

3D Flip Card Pattern

Module cards use a 3D flip to reveal settings. Perspective on the container, backface-visibility: hidden on each face, and rotateY for the flip.

.card-container {
  perspective: 1200px;

  &.flipped .card-front { transform: rotateY(-180deg); pointer-events: none; }
  &.flipped .card-back  { transform: rotateY(0deg);    pointer-events: all; }
}

.card {
  backface-visibility: hidden;
  transition: transform 0.6s cubic-bezier(0.4, 0, 0.2, 1);
}
.card-front { transform: rotateY(0deg);    }
.card-back  { transform: rotateY(180deg);  }

Button System

Primary (CTA)

.btn-primary {
  background: linear-gradient(135deg, #7c3aed, #3b82f6);
  color: white;
  border: none;
  border-radius: 12px;
  padding: 12px 24px;
  font-size: 14px;
  font-weight: 600;
  box-shadow: 0 4px 20px rgba(124, 58, 237, 0.4);
  transition: all 0.2s ease;

  &:hover {
    transform: translateY(-2px);
    box-shadow: 0 8px 30px rgba(124, 58, 237, 0.5);
  }
}

Glow Animation (for hero CTAs)

&.btn-glow {
  animation: glow 2s ease-in-out infinite;
}

@keyframes glow {
  0%, 100% { box-shadow: 0 4px 20px rgba(124, 58, 237, 0.4); }
  50%       { box-shadow: 0 4px 30px rgba(124, 58, 237, 0.6), 0 0 40px rgba(124, 58, 237, 0.3); }
}

Shine Effect (for generate/submit buttons)

.btn-generate {
  background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 50%, #a855f7 100%);
  position: relative;
  overflow: hidden;

  // Sweeping shine on hover
  &::before {
    content: '';
    position: absolute;
    top: 0; left: -100%;
    width: 100%; height: 100%;
    background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
    transition: left 0.6s ease;
  }

  &:hover::before { left: 100%; }

  &:hover {
    transform: translateY(-3px);
    box-shadow:
      0 8px 32px rgba(99, 102, 241, 0.45),
      0 4px 12px rgba(168, 85, 247, 0.3),
      inset 0 1px 0 rgba(255, 255, 255, 0.3);
  }
}

Secondary (Ghost Glass)

.btn-secondary {
  background: rgba(255, 255, 255, 0.08);
  color: rgba(255, 255, 255, 0.9);
  border: 1px solid rgba(255, 255, 255, 0.15);

  &:hover {
    background: rgba(255, 255, 255, 0.12);
    transform: translateY(-2px);
  }
}

Icon Button

.btn-icon {
  padding: 10px;
  background: rgba(255, 255, 255, 0.06);
  color: rgba(255, 255, 255, 0.7);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 12px;

  &:hover {
    background: rgba(255, 255, 255, 0.10);
    color: white;
  }

  &.active {
    background: rgba(124, 58, 237, 0.2);
    border-color: rgba(124, 58, 237, 0.4);
    color: #a78bfa;
  }
}

Ghost Button

.btn-ghost {
  background: transparent;
  color: rgba(255, 255, 255, 0.6);
  padding: 8px;

  &:hover {
    color: white;
    background: rgba(255, 255, 255, 0.08);
  }
}

Platform / Success Button

.btn-platform {
  background: linear-gradient(135deg, #10b981, #059669);
  color: white;
  border: none;

  &:hover {
    background: linear-gradient(135deg, #34d399, #10b981);
    box-shadow: 0 4px 16px rgba(16, 185, 129, 0.4);
  }
}

Size Variants

.btn      { padding: 12px 24px; font-size: 14px; }
.btn-sm   { padding:  6px 12px; font-size: 13px; }
.btn-lg   { padding: 18px 28px; font-size: 16px; font-weight: 700; }

Icon Container Patterns

Icons are always wrapped in a gradient-tinted rounded container.

// Large (hero / dashboard icon)
.icon-xl {
  width: 72px; height: 72px;
  background: linear-gradient(135deg, #7c3aed, #3b82f6);
  border-radius: 16px;
  box-shadow: 0 8px 32px rgba(124, 58, 237, 0.4);
  color: white;
  font-size: 28px;
}

// Medium (card icon)
.icon-md {
  width: 48px; height: 48px;
  background: linear-gradient(135deg, rgba(124, 58, 237, 0.2), rgba(59, 130, 246, 0.2));
  border-radius: 12px;
  color: #a78bfa;
  font-size: 18-20px;
}

// Small (mini card icon, back-side)
.icon-sm {
  width: 32px; height: 32px;
  background: linear-gradient(135deg, rgba(124, 58, 237, 0.3), rgba(59, 130, 246, 0.3));
  border-radius: 8px;
  color: #a78bfa;
  font-size: 14px;
}

// Suggestion / AI icon (indigo-to-violet)
.icon-ai {
  width: 44px; height: 44px;
  background: linear-gradient(135deg, #6366f1, #a855f7);
  border-radius: 12px;
  color: white;
  box-shadow: 0 2px 8px rgba(99, 102, 241, 0.25);
}

Color intent of icon tints:

  • Purple tint rgba(124, 58, 237, ...) → general module/feature
  • Blue tint rgba(59, 130, 246, ...) → built-in / system
  • Green tint rgba(52, 211, 153, ...) → success / deployed
  • Amber tint rgba(251, 191, 36, ...) → in-progress / building
  • Gray tint rgba(156, 163, 175, ...) → draft / inactive

Status Badge System

All status badges use the same anatomy: translucent background + matching text.

// Status pattern
.status-badge {
  padding: 4px 10px;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  border-radius: 6px;

  &.status-draft    { background: rgba(156, 163, 175, 0.15); color: #9ca3af; }
  &.status-building { background: rgba(251, 191, 36, 0.15);  color: #fbbf24; }
  &.status-testing  { background: rgba(168, 85, 247, 0.15);  color: #a855f7; }
  &.status-ready    { background: rgba(52, 211, 153, 0.15);  color: #34d399; }
  &.status-deployed { background: rgba(59, 130, 246, 0.15);  color: #3b82f6; }
}

// Source badges (custom / builtin / external)
.source-badge {
  padding: 4px 8px;
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  border-radius: 4px;

  &.source-custom   { background: rgba(139, 92, 246, 0.15); color: #a78bfa; }
  &.source-builtin  { background: rgba(59, 130, 246, 0.15); color: #60a5fa; }
  &.source-external { background: rgba(52, 211, 153, 0.15); color: #6ee7b7; }
}

Category Chip / Filter Chip

.category-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 16px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 20px;
  color: rgba(255, 255, 255, 0.6);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s ease;

  &:hover {
    background: rgba(255, 255, 255, 0.08);
    color: white;
  }

  &.active {
    background: linear-gradient(135deg, rgba(124, 58, 237, 0.2), rgba(59, 130, 246, 0.2));
    border-color: rgba(124, 58, 237, 0.4);
    color: white;
  }
}

Stats / Metrics Cards

.stat-card {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 20px;
  background: rgba(255, 255, 255, 0.04);
  backdrop-filter: blur(12px);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 16px;
  transition: all 0.2s ease;
  cursor: pointer;

  &:hover {
    background: rgba(255, 255, 255, 0.06);
    transform: translateY(-2px);
  }

  &.active {
    background: rgba(124, 58, 237, 0.1);
    border-color: rgba(124, 58, 237, 0.3);
  }

  .stat-value {
    font-size: 24px;
    font-weight: 700;
    color: white;
  }

  .stat-label {
    font-size: 13px;
    color: rgba(255, 255, 255, 0.5);
  }
}

Form Elements

Dark Theme Input

input, select, textarea {
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 10px;
  color: white;
  font-size: 14px;
  padding: 10px 40px 10px 14px; // with icon space
  outline: none;
  transition: all 0.2s ease;

  &::placeholder { color: rgba(255, 255, 255, 0.4); }

  &:focus {
    background: rgba(255, 255, 255, 0.08);
    border-color: rgba(124, 58, 237, 0.4);
    box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.12);
  }
}

Light Theme Input (ai-builder variant)

input, textarea {
  border: 2px solid rgba(203, 213, 225, 0.6);
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.8);
  color: #1e1e2e;
  font-size: 0.95rem;
  padding: 16px 18px;
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.04);
  transition: all 0.25s ease;

  &:focus {
    border-color: #6366f1;
    background: white;
    box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.12);
  }
}

Progress Bar

.progress-bar {
  height: 3px;   // thin version (inside cards)
  // height: 8px; // standard version
  background: rgba(255, 255, 255, 0.08);
  border-radius: 2px;
  overflow: hidden;

  .progress-fill {
    height: 100%;
    background: linear-gradient(90deg, #7c3aed, #3b82f6);
    // Or: linear-gradient(90deg, #6366f1, #10b981, #22c55e) — full spectrum
    border-radius: 2px;
    transition: width 0.3s ease;
    box-shadow: 0 0 12px rgba(124, 58, 237, 0.4);

    // Animated shine
    &::after {
      content: '';
      position: absolute;
      inset: 0;
      background: linear-gradient(90deg, transparent 0%, rgba(255,255,255,0.3) 50%, transparent 100%);
      animation: progressShine 2s ease-in-out infinite;
    }
  }
}

@keyframes progressShine {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(100%); }
}

Empty State

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 60px;
  background: rgba(255, 255, 255, 0.02);
  border: 2px dashed rgba(255, 255, 255, 0.1);
  border-radius: 20px;
  text-align: center;

  .empty-icon {
    width: 80px; height: 80px;
    background: rgba(124, 58, 237, 0.1);
    border-radius: 20px;
    margin-bottom: 20px;

    i { font-size: 32px; color: #7c3aed; }
  }

  h3 { margin: 0 0 8px; font-size: 18px; color: white; }
  p  { margin: 0 0 20px; color: rgba(255, 255, 255, 0.5); }
}

Loading State

Spinner

.loader {
  width: 40px; height: 40px;
  border: 3px solid rgba(124, 58, 237, 0.2);
  border-top-color: #7c3aed;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin { to { transform: rotate(360deg); } }

Full-Page Generation Overlay

.generation-card {
  background: rgba(var(--ux-surface-rgb), 0.8);
  backdrop-filter: blur(24px);
  border-radius: 24px;
  padding: 48px;
  text-align: center;
  max-width: 500px;

  .pulse-ring {
    position: absolute;
    width: 100%; height: 100%;
    border-radius: 50%;
    border: 2px solid var(--ux-primary);
    opacity: 0;
    animation: pulse-ring 2s ease-out infinite;

    &.delay-1 { animation-delay: 0.5s; }
    &.delay-2 { animation-delay: 1.0s; }
  }
}

@keyframes pulse-ring {
  0%   { transform: scale(0.8); opacity: 0.8; }
  100% { transform: scale(1.5); opacity: 0; }
}

Dividers

// Standard hairline
.divider {
  height: 1px;
  background: rgba(255, 255, 255, 0.04);
}

// Gradient fade-out divider (decorative)
.divider-gradient {
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent);
}

Custom Scrollbar

&::-webkit-scrollbar        { width: 4px; }
&::-webkit-scrollbar-track  { background: rgba(255, 255, 255, 0.05); border-radius: 2px; }
&::-webkit-scrollbar-thumb  {
  background: rgba(124, 58, 237, 0.4);
  border-radius: 2px;

  &:hover { background: rgba(124, 58, 237, 0.6); }
}

Header / Workbench Header

The workbench header has a signature 3px gradient accent line at the top.

.workbench-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20px 32px;
  background: linear-gradient(135deg, rgba(#252542, 0.95), rgba(#252542, 0.98));
  border-bottom: 1px solid rgba(#3d3d5c, 0.5);
  backdrop-filter: blur(12px);

  // Signature gradient top line
  &::before {
    content: '';
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 3px;
    background: linear-gradient(90deg, #6366f1 0%, #764ba2 50%, #f093fb 100%);
    opacity: 0.8;
  }
}

Step Navigation

Used in multi-step wizards (module workbench).

.step-item {
  padding: 14px 20px;
  background: rgba(#2d2d4a, 0.4);
  border: 1px solid rgba(#3d3d5c, 0.3);
  border-radius: 16px;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  backdrop-filter: blur(8px);

  // Active step
  &.active {
    background: linear-gradient(135deg, rgba(#6366f1, 0.15), rgba(#764ba2, 0.1));
    border-color: rgba(#6366f1, 0.5);
    box-shadow: 0 4px 20px rgba(#6366f1, 0.2), inset 0 1px 0 rgba(255,255,255,0.1);

    .step-title {
      background: linear-gradient(135deg, #818cf8, #c084fc);
      -webkit-background-clip: text;
      -webkit-text-fill-color: transparent;
    }
  }

  // Completed step
  &.step-complete .step-indicator {
    background: linear-gradient(135deg, #10b981, #059669);
    box-shadow: 0 4px 12px rgba(#10b981, 0.3);
  }

  // Partial step
  &.step-partial .step-indicator {
    background: linear-gradient(135deg, #f59e0b, #d97706);
    box-shadow: 0 4px 12px rgba(#f59e0b, 0.3);
  }
}

.step-connector {
  width: 32px; height: 3px;
  background: linear-gradient(90deg, rgba(#3d3d5c, 0.3), rgba(#3d3d5c, 0.5), rgba(#3d3d5c, 0.3));
  border-radius: 2px;
}

Grid Layouts

// Stat cards row (up to 5 columns)
.stats-bar {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 16px;

  @media (max-width: 1200px) { grid-template-columns: repeat(3, 1fr); }
  @media (max-width: 768px)  { grid-template-columns: repeat(2, 1fr); }
}

// Module cards (auto-fill, responsive)
.modules-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 20px;
}

// Template cards (4 → 2 → 1)
.templates-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;

  @media (max-width: 1200px) { grid-template-columns: repeat(2, 1fr); }
  @media (max-width: 768px)  { grid-template-columns: 1fr; }
}

// Main content + sidebar
.builder-content {
  display: grid;
  grid-template-columns: 1fr 380px;
  gap: 24px;

  @media (max-width: 1200px) { grid-template-columns: 1fr; }
}

Spacing Scale

All padding and gap values come from this consistent scale:

Token Value Common Use
--space-xs 4px Badge padding, tiny gaps
--space-sm 8px Icon gaps, chip inner
--space-md 12px Button gap, small card padding
--space-lg 16px Card gaps, grid gaps
--space-xl 20px Card padding, large gaps
--space-2xl 24px Page section padding
--space-3xl 32px Hero section padding

Typography

// Page title / Hero
h1 { font-size: 28px; font-weight: 700; color: #ffffff; letter-spacing: -0.02em; }

// Section title
.section-title { font-size: 18px; font-weight: 600; color: white; }

// Card title
.card-title    { font-size: 15px; font-weight: 600; color: white; line-height: 1.3; }

// Label / overline (uppercase caps)
.overline {
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: rgba(255, 255, 255, 0.4);
}

// Body text
.body         { font-size: 14-15px; color: rgba(255, 255, 255, 0.6); line-height: 1.5; }

// Caption / meta
.caption      { font-size: 12-13px; color: rgba(255, 255, 255, 0.35-0.5); }

// Micro
.micro        { font-size: 10-11px; text-transform: uppercase; letter-spacing: 0.05em; }

// Gradient text (hero moments)
.text-gradient {
  background: linear-gradient(135deg, #818cf8, #c084fc);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

// Monospace (code, versions)
.monospace {
  font-family: 'JetBrains Mono', 'Fira Code', monospace;
  background: rgba(255, 255, 255, 0.05);
  padding: 2px 8px;
  border-radius: 4px;
}

Border Radius Scale

$radius-xs:  4px;   // badges, tiny chips
$radius-sm:  8px;   // small buttons, inputs
$radius-md:  10px;  // action items, filter buttons
$radius-lg:  12px;  // standard buttons, icon containers
$radius-xl:  16px;  // cards, panels
$radius-2xl: 20px;  // hero panels, large cards
$radius-3xl: 24px;  // full panels (ai-builder)
$radius-pill: 20px; // category chips, status pills

Transition / Easing

// Standard interactive transition
transition: all 0.2s ease;

// Refined — use for cards and hover-lift effects
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);

// Smooth entrance / exit
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);

// Card flip (3D)
transition: transform 0.6s cubic-bezier(0.4, 0, 0.2, 1);

// Button hover lift
transform: translateY(-2px);  // standard hover
transform: translateY(-3px);  // hero CTA hover

// Slide-in animation
@keyframes slideUp {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: translateY(0); }
}

// Entrance animation
@keyframes fadeInUp {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: translateY(0); }
}

Complete Component Cheat Sheet

When building any new component, use this lookup table:

Element Style Recipe
Page background linear-gradient(135deg, #0f0f23, #1a1a3e, #0d1421) + ::before ambient radials
Card rgba(255,255,255,0.04) bg, blur(12px), 1px solid rgba(255,255,255,0.06), 16px radius
Card hover rgba(255,255,255,0.06) bg, rgba(124,58,237,0.3) border, translateY(-2px)
Hero section Same as card but rgba(255,255,255,0.03), blur(20px), 20px radius, 32px padding
Primary button linear-gradient(135deg, #7c3aed, #3b82f6), 0 4px 20px rgba(124,58,237,0.4) shadow
Primary button hover translateY(-2px), 0 8px 30px rgba(124,58,237,0.5)
Ghost/secondary button rgba(255,255,255,0.08) bg, rgba(255,255,255,0.15) border
Icon container (medium) linear-gradient(135deg, rgba(124,58,237,0.2), rgba(59,130,246,0.2)), 12px radius, #a78bfa color
Section title 18px, 600 weight, white, with #a78bfa tinted icon
Status: ready rgba(52,211,153,0.15) bg, #34d399 text
Status: building rgba(251,191,36,0.15) bg, #fbbf24 text
Status: deployed rgba(59,130,246,0.15) bg, #3b82f6 text
Status: draft rgba(156,163,175,0.15) bg, #9ca3af text
Category chip inactive rgba(255,255,255,0.04) bg, 20px radius
Category chip active linear-gradient(135deg, rgba(124,58,237,0.2), rgba(59,130,246,0.2)), purple border
Input (dark) rgba(255,255,255,0.06) bg, rgba(255,255,255,0.1) border, focus → purple border + ring
Progress bar linear-gradient(90deg, #7c3aed, #3b82f6), 3px thin / 8px standard height
Scrollbar 4px width, rgba(124,58,237,0.4) thumb
Header accent line 3px top border, linear-gradient(90deg, #6366f1, #764ba2, #f093fb)
Empty state border 2px dashed rgba(255,255,255,0.1), 20px radius
Divider 1px solid rgba(255,255,255,0.04) OR gradient fade variant
Transition all 0.2s ease standard / 0.3s cubic-bezier(0.4,0,0.2,1) smooth
Hover lift translateY(-2px)

Anti-Patterns (Do NOT Do These)

Wrong Right
Hardcoded white background: white on dark surfaces Use rgba(255,255,255,0.04) glass surfaces
Solid opaque borders border: 1px solid #333 Use rgba(255,255,255,0.06–0.15)
Flat monochrome icons Wrap in gradient icon container
border-radius: 4px on cards Minimum 16px for cards, 20px for panels
Saturated solid colors for status badges Use 15% opacity tinted backgrounds
No backdrop-filter on glass panels Always add blur(12–20px)
Missing hover state Every interactive element needs transition + hover
Gradient text without fallback color Always pair with color fallback

Quick-Start Template (Dark Dashboard Component)

:host {
  display: block;
  min-height: 100vh;
  background: linear-gradient(135deg, #0f0f23 0%, #1a1a3e 50%, #0d1421 100%);

  &::before {
    content: '';
    position: fixed;
    inset: 0;
    background:
      radial-gradient(ellipse at 20% 30%, rgba(124, 58, 237, 0.10), transparent 50%),
      radial-gradient(ellipse at 80% 70%, rgba(59, 130, 246, 0.08), transparent 50%);
    pointer-events: none;
    z-index: 0;
  }
}

.my-section {
  position: relative;
  z-index: 1;
  padding: 24px;
}

.my-card {
  background: rgba(255, 255, 255, 0.04);
  backdrop-filter: blur(12px);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 16px;
  padding: 20px;
  transition: all 0.2s ease;

  &:hover {
    background: rgba(255, 255, 255, 0.06);
    border-color: rgba(124, 58, 237, 0.3);
    transform: translateY(-2px);
  }
}

.my-cta {
  background: linear-gradient(135deg, #7c3aed, #3b82f6);
  color: white;
  border: none;
  border-radius: 12px;
  padding: 12px 24px;
  font-weight: 600;
  box-shadow: 0 4px 20px rgba(124, 58, 237, 0.4);
  cursor: pointer;
  transition: all 0.2s ease;

  &:hover {
    transform: translateY(-2px);
    box-shadow: 0 8px 30px rgba(124, 58, 237, 0.5);
  }
}

Light Builder Mode — Companion Guide

When building builder-type interfaces (configurators, wizards, settings panels), use the Light Builder mode. This shares the same accent system as the Dark Dashboard but inverts the surface hierarchy for a clean, airy, focused feel.

When to Use Light vs Dark

Mode Use For Examples
Dark Dashboard Monitoring, visualization, data-heavy pages Observatory, Workflow Builder, Agent Monitor
Light Builder Configuration, forms, editing, onboarding Vitto Maker, AI Builder, Settings panels

Light Mode Color System

// Page backgrounds
$bg-page:       linear-gradient(135deg, #f8f7ff 0%, #f0eeff 40%, #eef2ff 100%);
$bg-ambient:    radial-gradient(ellipse at 15% 20%, rgba(99, 102, 241, 0.06), transparent 50%),
                radial-gradient(ellipse at 85% 80%, rgba(139, 92, 246, 0.04), transparent 50%);

// Surface tiers (glass cards, panels)
$surface-card:       rgba(255, 255, 255, 0.85);   // default cards
$surface-card-hover: rgba(255, 255, 255, 0.95);   // hovered cards
$surface-sidebar:    rgba(255, 255, 255, 0.6);    // sidebar panels
$surface-input:      rgba(255, 255, 255, 0.7);    // inputs, search bars
$surface-input-focus: white;                        // focused inputs

// Text hierarchy
$text-primary:     #1e1e2e;
$text-secondary:   #4b5563;
$text-tertiary:    #9ca3af;

// Borders — use indigo-tinted alpha for cohesion
$border-light:     rgba(99, 102, 241, 0.08);
$border-default:   rgba(99, 102, 241, 0.12);
$border-hover:     rgba(99, 102, 241, 0.25);
$border-focus:     rgba(99, 102, 241, 0.25);

// Shadows — indigo-tinted for brand cohesion (NOT pure black)
$shadow-sm:  0 1px 3px rgba(99, 102, 241, 0.06), 0 1px 2px rgba(0, 0, 0, 0.04);
$shadow-md:  0 4px 12px rgba(99, 102, 241, 0.08), 0 2px 4px rgba(0, 0, 0, 0.04);
$shadow-lg:  0 4px 16px rgba(99, 102, 241, 0.10), 0 2px 4px rgba(0, 0, 0, 0.04);

Light Mode Background Pattern

:host {
  display: block;
  background: linear-gradient(135deg, #f8f7ff 0%, #f0eeff 40%, #eef2ff 100%);
  position: relative;

  &::before {
    content: '';
    position: fixed;
    inset: 0;
    background:
      radial-gradient(ellipse at 15% 20%, rgba(99, 102, 241, 0.06), transparent 50%),
      radial-gradient(ellipse at 85% 80%, rgba(139, 92, 246, 0.04), transparent 50%);
    pointer-events: none;
    z-index: 0;
  }
}

Light Mode Card

.card {
  background: rgba(255, 255, 255, 0.85);
  backdrop-filter: blur(12px);
  border: 1px solid rgba(99, 102, 241, 0.08);
  border-radius: 16px;
  padding: 20px;
  box-shadow: 0 1px 4px rgba(99, 102, 241, 0.06), 0 1px 2px rgba(0, 0, 0, 0.03);
  transition: all 0.2s ease;

  &:hover {
    box-shadow: 0 4px 16px rgba(99, 102, 241, 0.1), 0 2px 4px rgba(0, 0, 0, 0.04);
    border-color: rgba(99, 102, 241, 0.15);
  }
}

Light Mode Input

input, select, textarea {
  background: rgba(255, 255, 255, 0.7);
  border: 1px solid rgba(99, 102, 241, 0.08);
  border-radius: 10px;
  color: #1e1e2e;
  font-size: 13px;
  padding: 10px 14px;
  transition: all 0.15s ease;

  &::placeholder { color: #9ca3af; }

  &:focus {
    background: white;
    border-color: rgba(99, 102, 241, 0.25);
    box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.06);
  }
}

Light Mode Badges / Pills

Use color-mix() for automatic accent tinting:

.badge {
  font-size: 11px;
  font-weight: 600;
  padding: 3px 10px;
  border-radius: 10px;
  background: color-mix(in srgb, var(--accent, #818cf8) 8%, transparent);
  color: var(--accent, #818cf8);
  border: 1px solid color-mix(in srgb, var(--accent, #818cf8) 12%, transparent);
}

Light Mode Toggle Switch

.switch {
  width: 38px; height: 22px;
  border-radius: 11px;
  border: 1px solid rgba(0, 0, 0, 0.08);
  background: rgba(0, 0, 0, 0.06);
  position: relative;

  &--on {
    background: color-mix(in srgb, var(--accent, #818cf8) 85%, white);
    border-color: color-mix(in srgb, var(--accent, #818cf8) 30%, transparent);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent, #818cf8) 10%, transparent);
  }

  .knob {
    width: 16px; height: 16px;
    border-radius: 50%;
    background: white;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
    position: absolute; top: 2px; left: 2px;
    transition: transform 0.2s ease;

    .switch--on & { transform: translateX(16px); }
  }
}

Light Mode Component Cheat Sheet

Element Light Mode Recipe
Page background linear-gradient(135deg, #f8f7ff, #f0eeff, #eef2ff) + ::before ambient radials (opacity 0.04-0.06)
Card rgba(255,255,255,0.85) bg, blur(12px), 1px solid rgba(99,102,241,0.08), indigo-tinted shadow
Card hover 0.95 bg, rgba(99,102,241,0.15) border, larger shadow
Sidebar rgba(255,255,255,0.6) bg, blur(20px) backdrop
Primary button Same gradient as dark mode: linear-gradient(135deg, #7c3aed, #3b82f6)
Ghost button rgba(255,255,255,0.8) bg, rgba(99,102,241,0.12) border
Input rgba(255,255,255,0.7) bg, focus → white + indigo ring
Text primary #1e1e2e (dark navy)
Text secondary #4b5563 (gray-600)
Text tertiary #9ca3af (gray-400)
Border rgba(99,102,241,0.08) light, 0.12 default, 0.25 hover/focus
Shadows Always indigo-tinted: rgba(99,102,241,0.06-0.10) + small black component
Icon containers Same as dark: color-mix(in srgb, var(--accent) 10%, transparent) with 1px solid at 12%
Badge/pill color-mix(in srgb, var(--accent) 8%, transparent) bg + 12% border
Scrollbar 4px width, rgba(99,102,241,0.15-0.3) thumb

Light Mode Anti-Patterns

Wrong Right
Pure #ffffff backgrounds everywhere Use rgba(255,255,255,0.85) glass surfaces
border: 1px solid #e5e7eb (generic gray) Use rgba(99,102,241,0.08) (indigo-tinted) for brand cohesion
box-shadow with pure black Use indigo-tinted shadows for warmth
Dark text directly on light background (#000) Use #1e1e2e (dark navy) for softer contrast
No backdrop-filter on light panels Add blur(12-20px) for frosted glass effect
Missing ambient glow Add subtle rgba(99,102,241,0.04-0.06) radial gradients

Last updated: March 4, 2026 — Session 177 | Source: libs/libs-structural/modularity-lib/src/lib/components/**/*.scss, libs/libs-ai/vitto-maker/src/lib/components/**/*.scss