npm package: @libs-ui/services-config-project
Description: Service cấu hình toàn cục cho libs-ui: theme color, font family, heading styles, button colors/sizes/statuses/tabs. Inject **một lần** trong `AppComponent` — áp dụng ngay cho toàn bộ ứng dụng thông qua CSS variables.
Latest version: 0.2.356-23

# Config Project Service

Service cấu hình toàn cục cho libs-ui: theme color, font family, heading styles, button colors/sizes/statuses/tabs. Inject **một lần** trong `AppComponent` — áp dụng ngay cho toàn bộ ứng dụng thông qua CSS variables.

## Tính năng

- ✅ Theme color — tự động tính 20+ CSS color variables từ một màu gốc
- ✅ Custom font family qua FontFace API (load dynamic, không cần @font-face CSS)
- ✅ Heading styles — 7 levels × 4 weights (h1r → h7b)
- ✅ Button colors — 14 built-in types + extensible qua `FunctionGetConfigButtonIncludes`
- ✅ Button status colors — 8 màu mặc định + custom
- ✅ Button tab colors — 8 màu với background active và badge
- ✅ Signal reactivity — thay đổi tức thì, không cần reload
- ✅ Global CSS utility classes (border, shadow, disable, readonly, selection...)

## Cài đặt

```bash
npm install @libs-ui/services-config-project
```

## Import

```typescript
import { LibsUiConfigProjectService } from '@libs-ui/services-config-project';
```

## Quick Start

Inject **một lần** trong `AppComponent` và set config ngay khi khởi động:

```typescript
import { Component, inject, OnInit } from '@angular/core';
import { LibsUiConfigProjectService } from '@libs-ui/services-config-project';

@Component({ standalone: true, ... })
export class AppComponent implements OnInit {
  private configService = inject(LibsUiConfigProjectService);

  ngOnInit() {
    // Bước 1: Set brand/theme color
    this.configService.ThemeColor = '#226ff5';

    // Bước 2 (tùy chọn): Set custom font
    this.configService.ConfigFont = {
      name: 'Inter',
      uri_regular: '/assets/fonts/Inter-Regular.ttf',
      uri_medium: '/assets/fonts/Inter-Medium.ttf',
      uri_semibold: '/assets/fonts/Inter-SemiBold.ttf',
      uri_bold: '/assets/fonts/Inter-Bold.ttf',
    };
  }
}
```

## Ví dụ

### Thay đổi Theme Color (Multi-tenant)

```typescript
// Sau khi fetch tenant config từ API:
this.configService.ThemeColor = tenantConfig.brandColor;
// → 20+ CSS variables được cập nhật ngay lập tức
```

### Override màu individual

```typescript
this.configService.BorderColor = '#d1d5db';
this.configService.TextErrorColor = '#dc2626';
this.configService.BackgroundDisableColor = '#f3f4f6';
this.configService.TextDisableColor = '#9ca3af';
```

### Custom button type

```typescript
this.configService.FunctionGetConfigButtonIncludes = (rootColor) => ({
  'button-brand': {
    configStepColor: {
      text: 'white',
      text_hover: 'white',
      text_active: 'white',
      text_disable: '#CDD0D6',
      background: 0,
      background_hover: 20,
      background_active: -20,
      background_disable: '#F8F9FA',
      border: 0,
      border_hover: 20,
      border_active: -20,
      border_disable: '#F8F9FA',
    },
    rootColor: '#e91e63',
  },
});
```

### Sử dụng CSS Variables trong SCSS

```scss
// Dùng biến thay vì hardcode màu
.my-button {
  background: var(--libs-ui-color-default);
  border: 1px solid var(--libs-ui-color-light-1);

  &:hover {
    background: var(--libs-ui-color-light-3);
  }
  &:disabled {
    background: var(--libs-ui-color-background-disable);
    color: var(--libs-ui-color-text-disable);
  }
}
```

## API — Setters

| Setter                            | Type                        | Default              | Mô tả                                      |
| --------------------------------- | --------------------------- | -------------------- | ------------------------------------------ |
| `ThemeColor`                      | `string`                    | `'#226ff5'`          | Màu chủ đạo — sinh 20+ CSS color variables |
| `BorderColor`                     | `string`                    | `'#e6e7ea'`          | Màu border (--libs-ui-color-border)        |
| `BorderErrorColor`                | `string`                    | `'#ee2d41'`          | Màu border error                           |
| `TextErrorColor`                  | `string`                    | `'#ff5454'`          | Màu text error                             |
| `IconHoverDangerColor`            | `string`                    | `'#f15767'`          | Màu icon hover danger                      |
| `BackgroundDisableColor`          | `string`                    | `'#f8f9fa'`          | Background disabled                        |
| `TextDisableColor`                | `string`                    | `'#9ca2ad'`          | Text color disabled                        |
| `TextReadonlyColor`               | `string`                    | `'#071631'`          | Text color readonly                        |
| `BackgroundReadonlyColor`         | `string`                    | `'#f8f9fa'`          | Background readonly                        |
| `BackgroundUserSelection`         | `string`                    | `'#00000040'`        | Text selection background                  |
| `BackgroundList`                  | `string`                    | `'#f8f9fa'`          | Dropdown/list item background              |
| `BackgroundListHover`             | `string`                    | `'#f8f9fa'`          | List item hover background                 |
| `BackgroundListHoverDanger`       | `string`                    | `'#fef5f6'`          | List item hover danger background          |
| `ConfigFont`                      | `ILibsUiConfigFontFamily`   | SVN-Poppins          | Font family + URI files                    |
| `ConfigFontHead`                  | `ILibsUiConfigFontHeading`  | 7 levels × 4 weights | Heading styles (h1r→h7b)                   |
| `ConfigButtonStatus`              | `ILibsUiConfigButtonStatus` | 8 màu                | Badge status colors                        |
| `ConfigButtonTab`                 | `ILibsUiConfigButtonTab`    | 8 màu                | Tab button colors                          |
| `FunctionGetConfigButtonIncludes` | `Function`                  | `() => {}`           | Hàm thêm custom button types               |

## API — Getters

| Getter               | Returns                                   | Mô tả                                         |
| -------------------- | ----------------------------------------- | --------------------------------------------- |
| `ConfigButton`       | `Signal<{ [key: string]: IColorButton }>` | Tất cả button color configs (computed Signal) |
| `ConfigButtonStatus` | `ILibsUiConfigButtonStatus`               | Current button status config                  |

## API — Methods

| Method                                      | Returns           | Mô tả                                                  |
| ------------------------------------------- | ----------------- | ------------------------------------------------------ |
| `colorStepContrastFromOrigin(step, color?)` | `{ light, dark }` | Tính màu lighter/darker N steps                        |
| `setupFontFamily(doc?)`                     | `void`            | Load font vào document (public để dùng cho shadow DOM) |

## CSS Variables được tạo ra

| Variable                             | Mô tả                                       |
| ------------------------------------ | ------------------------------------------- |
| `--libs-ui-color-default`            | ThemeColor gốc                              |
| `--libs-ui-color-light-1`            | ThemeColor + 20 steps sáng                  |
| `--libs-ui-color-light-2`            | ThemeColor + 90 steps sáng                  |
| `--libs-ui-color-light-3`            | ThemeColor + 95 steps sáng (background nhẹ) |
| `--libs-ui-color-dark`               | ThemeColor - 20 steps tối                   |
| `--libs-ui-color-border`             | BorderColor                                 |
| `--libs-ui-color-border-error`       | BorderErrorColor                            |
| `--libs-ui-color-text-error`         | TextErrorColor                              |
| `--libs-ui-color-text-disable`       | TextDisableColor                            |
| `--libs-ui-color-background-disable` | BackgroundDisableColor                      |
| `--libs-ui-font-family-name`         | Font family name                            |

## Types

```typescript
interface ILibsUiConfigFontFamily {
  name: string;
  uri_regular: string;
  uri_medium: string;
  uri_semibold: string;
  uri_bold?: string;
}

interface ILibsUiConfigButtonStatus {
  [key: string]: { color: string; background?: string };
}

interface ILibsUiConfigButtonTab {
  [key: string]: { color: string; background?: string; background_badge?: string };
}

interface IColorButton {
  configStepColor: { text, text_hover, text_active, text_disable, background?, ... };
  rootColor: string;
}
```

## Lưu ý quan trọng

- **Inject một lần** trong `AppComponent` — service là `providedIn: 'root'`, mọi nơi đều dùng chung instance
- **Signal reactivity** — thay đổi bất kỳ setter nào → Angular `effect()` tự chạy lại → CSS vars cập nhật ngay
- **Font URIs** phải accessible từ browser (URL tuyệt đối hoặc tương đối từ root). Load bằng FontFace API — không cần `@font-face` trong CSS
- **String.prototype** được extend global (replaceAt, occurrencesByCharacter, indexesOfCharacter) khi service khởi tạo
- **`configService.ThemeColor = '#e91e63'`** (setter syntax) — không phải method call