# Flux UI

A custom, lightweight CSS/SASS framework built for microfrontend architectures. Optimized for Module Federation with type-safe design tokens and minimal bundle footprint.

## Features

- ✨ **Custom Foundation** - Built from scratch, no framework bloat
- 📦 **Lightweight** - 15-25KB gzipped (vs 150-230KB for Bootstrap/Tailwind)
- 🎨 **Type-Safe Tokens** - Design tokens exported as TypeScript constants
- 🔄 **MFE-Optimized** - CSS loads once in shell, all remotes reuse it
- 🎯 **CSS Layers** - Modern cascade management prevents namespace conflicts
- 🌙 **Runtime Theming** - CSS variables enable dynamic theme changes
- 📱 **Responsive** - Mobile-first breakpoint system
- ♿ **Accessible** - WCAG-compliant patterns and defaults

## Installation

### NPM

```bash
npm install @vialiq/flux-ui
# or
yarn add @vialiq/flux-ui
```

### Monorepo (Local)

```typescript
// In tsconfig.base.json (already configured)
{
  "compilerOptions": {
    "paths": {
      "@vialiq/flux-ui": ["libs/flux-ui/src/index.ts"],
      "@vialiq/flux-ui/tokens": ["libs/flux-ui/src/tokens/index.ts"],
      "@vialiq/flux-ui/styles": ["libs/flux-ui/src/styles/index.ts"]
    }
  }
}
```

## Integration Guide

### Option 1: SCSS Consumer (Recommended for Angular/Nx Apps)

**Best for:** Angular apps, build-time optimization, theming

```scss
// In your app/src/styles.scss (or global style)

@use '@vialiq/flux-ui/styles/_variables.scss' as *;
@use '@vialiq/flux-ui/styles/_reset.scss';
@use '@vialiq/flux-ui/styles/_layout.scss';
@use '@vialiq/flux-ui/styles/_utilities.scss';

// Now all utilities available:
// - Classes: .p-md, .text-lg, .bg-primary, .flex, .gap-sm, etc.
// - Variables: $spacing-md, $color-primary, $font-size-base, etc.
// - Theming: @use '@vialiq/flux-ui/styles/theme' as theme; then @include theme.vi-theme(theme.$vi-theme--light, $emit-custom-properties: true);
```

**Advantages:**
- ✅ Tree-shaking: Only include used styles (via build process)
- ✅ Variable access: Use `$spacing-md` in your component SCSS
- ✅ Theming: @include mixins for custom theme scopes
- ✅ Smaller bundle: Only compiled styles you actually use
- ✅ Full control: Extend/override tokens before build

**Example Component (Angular):**
```scss
// button.component.scss
@use '@vialiq/flux-ui/styles/variables' as *;
@use '@vialiq/flux-ui/styles/theme' as theme;

:host {
  @include theme.vi-theme(theme.$vi-theme--light, $emit-custom-properties: true);
}

.button {
  padding: $spacing-sm $spacing-md;
  background-color: $color-primary;
  border-radius: $border-radius-md;
  font-weight: $font-weight-semibold;
  
  &:hover {
    background-color: $color-primary-hover; // Theme token
  }
}
```

### Option 2: CSS-Only Consumer (Plain HTML / No Build)

**Best for:** Static sites, CDN delivery, Shadow DOM isolation, Storybook

```html
<!-- In your HTML <head> -->
<link rel="stylesheet" href="./node_modules/@vialiq/flux-ui/flux-ui.css">

<!-- Now all utilities available via classes -->
<div class="flex justify-center items-center gap-md p-lg">
  <h1 class="text-3xl font-bold text-primary">Hello</h1>
  <button class="px-md py-sm bg-success text-grey-100 rounded-md">Action</button>
</div>
```

**Advantages:**
- ✅ Zero build step needed
- ✅ Works anywhere (plain HTML, iframes, Shadow DOM)
- ✅ CDN-friendly: Single CSS file
- ✅ Fast delivery: CSS pre-compiled and minified
- ✅ No SCSS knowledge required

**Size & Performance:**
- Uncompressed: 35 KB
- Gzipped: ~8 KB
- Source map: 8.6 KB (for debugging)

### Option 3: Hybrid (TypeScript + CSS)

**Best for:** Web Components (Lit, vanilla JS)

```typescript
// In your component file
import '@vialiq/flux-ui/flux-ui.css';          // Import pre-compiled CSS
import { tokens } from '@vialiq/flux-ui';      // Import tokens for JS styling

class MyComponent extends LitElement {
  static styles = css`
    :host {
      padding: ${tokens.spacing.md};
      color: var(--vi-color-foreground);
    }
  `;
  
  render() {
    return html`
      <div class="flex gap-md p-lg">
        <span>Content</span>
      </div>
    `;
  }
}
```

**Advantages:**
- ✅ Pre-compiled CSS for utilities
- ✅ Type-safe tokens for JS-driven styles
- ✅ Works with Web Components & frameworks
- ✅ Best of both worlds

## Using Tokens

```typescript
import { tokens } from '@vialiq/flux-ui';

const buttonStyle = {
  padding: tokens.spacing.md,        // 24px
  backgroundColor: tokens.colors.primary,
  borderRadius: tokens.borders.radius.md
};
```

### Using Utilities

```html
<div class="flex justify-between items-center gap-md p-lg">
  <h1 class="text-2xl font-bold">Title</h1>
  <button class="bg-primary text-grey-100 rounded-md">Action</button>
</div>
```

## Token Categories

| Category | Examples | Count |
|----------|----------|-------|
| **Colors** | primary, secondary, success, error, neutral-50 to 900 | 20+ |
| **Spacing** | xs (8px), sm (16px), md (24px), ... 3xl (56px) | 7 |
| **Typography** | text-xs to text-3xl, font-light to font-bold | 15+ |
| **Shadows** | shadow-sm, md, lg, xl | 4 |
| **Borders** | border-radius: sm to xl, border-width: thin to thick | 8 |
| **Z-Index** | dropdown, modal, tooltip | 10 |
| **Breakpoints** | xs, sm, md, lg, xl, 2xl | 6 |

## Documentation

### Strategic & Planning
- **[ADR-001-component-library-strategy.md](./docs/ADR-001-component-library-strategy.md)** ⭐ **START HERE** — Angular vs Web Components, build vs buy decision
- **[QUICK-COMPARISON.md](./docs/QUICK-COMPARISON.md)** - CSS framework decision matrix
- **[FRAMEWORK-COMPARISON.md](./docs/FRAMEWORK-COMPARISON.md)** - Detailed comparison with Bootstrap, Tailwind, Material, etc.
- **[COMPONENT-LAYER-ROADMAP.md](./docs/COMPONENT-LAYER-ROADMAP.md)** - Angular component implementation guide

### Technical Reference
- **[ARCHITECTURE.md](./docs/ARCHITECTURE.md)** - Technical deep dive
- **[TOKEN-SPEC.md](./docs/TOKEN-SPEC.md)** - Complete token reference
- **[CSS-DECISION.md](./docs/CSS-DECISION.md)** - Why we chose a custom framework
- **[USAGE-GUIDE.md](./docs/USAGE-GUIDE.md)** - How to use in your apps

## Architecture

```
Design System (Shared)
│
├── Init in Shell
│   └── Load CSS once at bootstrap
│
└── Consumed by Remotes
    ├── Remote 1: Import tokens, reuse CSS ✓
    ├── Remote 2: Import tokens, reuse CSS ✓
    └── Remote 3: Import tokens, reuse CSS ✓
```

**Result:** CSS file size ÷ by N MFEs, not multiplied!

## MFE Integration Pattern

### Shell App

```typescript
// apps/shell/src/bootstrap.ts
import '@vialiq/flux-ui/flux-ui.css';  // Load once for all MFEs

bootstrapApplication(App).catch(err => console.error(err));
```

### Remote App

```typescript
// apps/remote1/src/bootstrap.ts
// ❌ DO NOT import styles (shell already loaded them)

import { tokens } from '@vialiq/flux-ui';  // ✅ Import tokens only

bootstrapApplication(RemoteEntry).catch(err => console.error(err));
```

## Token Export Formats

### TypeScript (Type-Safe)

```typescript
import { tokens } from '@vialiq/flux-ui';

const value = tokens.spacing.md;  // IDE autocomplete, type checking
```

### SCSS (Build-Time)

```scss
@use '@vialiq/flux-ui/styles/variables' as *;

.button {
  padding: $spacing-md;
  background: $color-primary;
}
```

### CSS (Runtime)

```css
:root {
  --vi-spacing-md: 24px;
  --vi-color-primary: #0066cc;
}

.button {
  padding: var(--vi-spacing-md);
  background: var(--vi-color-primary);
}
```

## Utility Classes

### Spacing

```html
<div class="m-md">Margin 24px</div>
<div class="p-lg" style="margin-left: auto; margin-right: auto; width: max-content;">Padding 32px, centered</div>
<div class="mt-sm mb-lg">Top margin 16px, bottom 32px</div>
```

### Typography

```html
<h1 class="text-3xl font-bold">Heading</h1>
<p class="text-base leading-relaxed">Body text with comfortable spacing</p>
<code class="text-sm text-grey-600">Code snippet</code>
```

### Layout

```html
<div class="flex justify-between items-center gap-md">Flexbox</div>
<div class="grid grid-cols-3 gap-lg">Grid 3 columns</div>
```

### Colors

```html
<p class="text-primary">Colored text</p>
<div class="bg-success text-grey-100">Success state</div>
<div class="border-lg border-error">Error border</div>
```

## Theming

### Light/Dark Mode

```typescript
// Change theme at runtime
document.documentElement.setAttribute('data-theme', 'dark');

// Update CSS variables
const root = document.documentElement;
root.style.setProperty('--vi-color-primary', '#60a5fa');
```

**SCSS:**

```scss
:root {
  --vi-color-background: #ffffff;
}

:root[data-theme="dark"] {
  --vi-color-background: #1f2937;
}
```

## Bundle Impact

- **Design System Core:** 15-25KB gzipped (loaded once in shell)
- **Per Remote App:** 0KB overhead (reuses shell CSS)
- **Tokens Module:** 2-3KB (tree-shakeable)

**Comparison:**
- Bootstrap per app: 180-230KB × N remotes
- Tailwind per app: 20-80KB × N remotes  
- **Design System (ours): 20-30KB × 1 (shell only)** ✓

## CSS Layers

All styles use CSS Layers for safe cascade management:

```scss
@layer reset, components, utilities;

@layer reset {
  /* Browser defaults, lowest priority */
}

@layer components {
  /* Component styles, medium priority */
}

@layer utilities {
  /* Utility classes, highest priority */
}
```

This prevents specificity wars between shell and remote app styles.

## Framework Support

Works with any JavaScript framework:
- ✅ Angular
- ✅ React
- ✅ Vue
- ✅ Web Components
- ✅ Vanilla JavaScript

## Performance

- **CSS Parse Time:** ~2-3ms (minimal)
- **CSS Variable Access:** ~4-6ms for 100 lookups
- **No JavaScript overhead** for core styles
- **Tree-shakeable tokens** (unused exports removed)

## Accessibility

- ✅ WCAG AA compliant color contrast
- ✅ Focus states built-in
- ✅ Semantic HTML patterns
- ✅ Reduced motion support ready
- ✅ Responsive `rem` scaling based on root font size

### Responsive Typography & Rem Scaling
Flux UI strictly uses `rem` units for typography and spacing to ensure accessibility. By default, it assumes a standard browser root font size of `16px`.

If your application uses a custom root font size (such as the `62.5%` or `10px` hack), you must configure Flux UI to scale its internal calculations accordingly:

```scss
// In your application's main SCSS file:
@use '@vialiq/flux-ui/styles' with (
  $vi-rem-base: 10px
);
```
This ensures that a component designed to be `16px` tall will correctly output `1.6rem`, rendering exactly 16 pixels at runtime against your custom 10px root.

### CSS Unit Guidelines
To maintain a robust, scalable, and accessible UI, Flux UI strictly adheres to the following unit rules:

- **`rem`**: Used for **Typography**, **Spacing** (margin, padding, gap), and **Interactive Form Control Sizing** (button heights, input widths, etc.). This guarantees that everything defining the core layout grid and text hierarchy scales fluidly when a user changes their browser root font size for accessibility.
- **`px`**: Reserved exclusively for rigid geometries that must never scale or blur. Used for **Borders** (`1px solid`), **Shadows** (offsets and blurs), small **Optical Adjustments** (e.g. `2px` focus outline offset), and **Visually Hidden Hacks** (e.g. `1px` clipping for screen readers).
- **`dvh` / `dvw`** (with `vh` / `vw` fallback): Used for **Viewport-Relative Layouts**, such as full-screen modal overlays, drawer max-heights, or sticky banners that must span the entire screen regardless of the parent container size. Dynamic viewport units correctly account for mobile browser UI (like address bars) expanding and contracting.
- **`%`**: Used for **Container-Relative Fluidity**, such as a button being `width: 100%` of its parent column, or grid layouts.

## Contributing

To add a new token or component:

1. Update `src/tokens/index.ts` and `src/styles/_variables.scss`
2. Add CSS custom property in `:root`
3. Update relevant `src/styles/*.scss` file
4. Document in `docs/TOKEN-SPEC.md`
5. Create component in `src/components/` if needed

## Versioning

- **Major:** Breaking changes (token renamed/removed)
- **Minor:** New tokens/components
- **Patch:** Bug fixes (styling corrections)

## License

MIT

## Questions?

Refer to:
- [USAGE-GUIDE.md](./docs/USAGE-GUIDE.md) for implementation details
- [ARCHITECTURE.md](./docs/ARCHITECTURE.md) for technical decisions
- [TOKEN-SPEC.md](./docs/TOKEN-SPEC.md) for token reference
