From fastlane-ui-design
Build scalable design systems with Pangea design tokens, Angular Material theming, and component architecture patterns for Fastlane. Use when implementing token-based theming, building Angular component abstractions, or establishing Pangea-aligned component foundations.
How this skill is triggered — by the user, by Claude, or both
Slash command
/fastlane-ui-design:design-system-patternsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Master design system architecture to create consistent, maintainable, and scalable UI foundations across the Fastlane application.
Master design system architecture to create consistent, maintainable, and scalable UI foundations across the Fastlane application.
:root)// Angular component file — use Pangea tokens from _root
.my-component {
color: var(--on-surface);
background: var(--surface);
padding: var(--spacing-sm); // 16px
&__title {
color: var(--on-surface);
font-weight: 600;
}
&__secondary-text {
color: var(--pangea-text-secondary);
}
:host-context(body.dark-theme) & {
background: var(--surface-alt);
}
}
import { Injectable, signal } from '@angular/core';
@Injectable({ providedIn: 'root' })
export class ThemeService {
private readonly darkMode = signal<boolean>(false);
readonly isDark = this.darkMode.asReadonly();
constructor() {
this.initializeTheme();
}
private initializeTheme(): void {
const isDark = localStorage.getItem('theme') === 'dark' ||
(window.matchMedia('(prefers-color-scheme: dark)').matches &&
!localStorage.getItem('theme'));
if (isDark) {
this.applyDarkTheme();
}
}
toggleDark(): void {
const isDark = !this.darkMode();
this.darkMode.set(isDark);
if (isDark) {
this.applyDarkTheme();
} else {
this.applyLightTheme();
}
localStorage.setItem('theme', isDark ? 'dark' : 'light');
}
private applyDarkTheme(): void {
document.body.classList.add('dark-theme');
this.darkMode.set(true);
}
private applyLightTheme(): void {
document.body.classList.remove('dark-theme');
this.darkMode.set(false);
}
}
/* Layer 1: Primitive tokens (raw values) */
:root {
/* Pangea color palette — defined once */
--color-primary: #2563eb;
--color-primary-dark: #1e40af;
--color-success: #16a34a;
--color-error: #dc2626;
--color-warning: #f59e0b;
/* Neutral grays */
--color-gray-50: #f9fafb;
--color-gray-100: #f3f4f6;
--color-gray-900: #111827;
/* Spacing scale (8px base) */
--spacing-xs: 0.5rem; /* 8px */
--spacing-sm: 1rem; /* 16px */
--spacing-md: 1.5rem; /* 24px */
--spacing-lg: 2rem; /* 32px */
--spacing-xl: 2.5rem; /* 40px */
/* Font sizes */
--font-size-sm: 0.875rem;
--font-size-base: 1rem;
--font-size-lg: 1.125rem;
--radius-sm: 0.25rem;
--radius-md: 0.5rem;
--radius-lg: 1rem;
}
/* Layer 2: Semantic tokens (light mode) */
:root {
--surface: white;
--surface-alt: #f9fafb;
--on-surface: #111827;
--pangea-text-secondary: #6b7280;
--border-default: #e5e7eb;
--interactive-primary: var(--color-primary);
--interactive-primary-hover: var(--color-primary-dark);
}
/* Layer 3: Dark mode overrides */
body.dark-theme {
--surface: #111827;
--surface-alt: #1f2937;
--on-surface: #f9fafb;
--pangea-text-secondary: #9ca3af;
--border-default: #374151;
--interactive-primary: var(--color-primary);
}
/* Layer 4: Component tokens (specific usage) */
:root {
--button-primary-bg: var(--interactive-primary);
--button-primary-text: white;
--button-primary-radius: var(--radius-md);
--button-padding-x: var(--spacing-sm);
--button-padding-y: 0.5rem;
}
<!-- Primary action — preferred action -->
<button mat-raised-button color="primary">Submit</button>
<!-- Success action (secondary emphasis) -->
<button mat-raised-button color="accent">Confirm</button>
<!-- Destructive action (danger) -->
<button mat-raised-button color="warn">Delete</button>
<!-- Secondary action (outlined) -->
<button mat-stroked-button>Cancel</button>
<!-- Tertiary action (text-only) -->
<button mat-icon-button aria-label="More actions">
<mat-icon>more_vert</mat-icon>
</button>
import {
Component,
Input,
input,
ChangeDetectionStrategy,
} from '@angular/core';
import { CommonModule } from '@angular/common';
import { MatButtonModule } from '@angular/material/button';
@Component({
selector: 'app-action-button',
standalone: true,
imports: [CommonModule, MatButtonModule],
template: `
<button
mat-raised-button
[color]="color()"
[disabled]="disabled()"
(click)="handleClick()"
class="action-button"
>
<ng-content />
</button>
`,
styleUrl: './action-button.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ActionButtonComponent {
readonly color = input<'primary' | 'accent' | 'warn'>('primary');
readonly disabled = input<boolean>(false);
handleClick(): void {
// Component logic
}
}
SCSS:
.action-button {
min-width: 120px;
:host-context(body.dark-theme) & {
// Material handles dark mode automatically
// but you can override specific tokens if needed
}
}
:host for encapsulationFastlane uses Pangea's token system:
:root (default)body.dark-themeapps/web/src/styles.scss contains token definitionsThemeService to switch modespangea-design-system skill — complete Pangea token catalog and Material slot remappingdesign-system-patterns — Angular Material integration patternsvisual-design-foundations — token vocabulary and semantic namingGuides collaborative design exploration before implementation: explores context, asks clarifying questions, proposes approaches, and writes a design doc for user approval.
Creates structured, bite-sized implementation plans from specs or requirements before writing code. Useful for breaking down multi-step tasks into testable steps with file structure and task boundaries.
Implements work from a spec or tickets using TDD at agreed seams, with regular typechecking and test runs, followed by code review.
npx claudepluginhub pat-richardson/fastlane-ui-design --plugin fastlane-ui-design