# Variables Directory

> **⚠️ Important Notice**: This directory contains LESS variable files for **backward compatibility only**. LESS variable overriding is deprecated and no longer functional.

---

## For End Users: LESS Variable Deprecation

### ⚠️ What Changed

**LESS variable overriding is deprecated and no longer applies branding changes.**

If you were previously customizing your application with LESS variable overrides like this:

```less
// ❌ DEPRECATED - No longer works
@import '~@c8y/style/extend.less';

@brand-primary: #custom-color;
@navigator-bg-color: #custom-nav;
@header-text-color: #custom-header;
```

**This approach no longer applies your customizations** because `@c8y/style` now uses SCSS, not LESS, as the primary build system (January 2026).

### ✅ Migration Options

#### Option 1: CSS Custom Properties (Recommended)

Use CSS custom properties for theming at build time or runtime:

```css
/* Override in your custom CSS/SCSS */
:root {
  --brand-primary: #1976d2;
  --navigator-bg-color: #1565c0;
  --main-header-background-default: #ffffff;
  --main-header-text-color-default: #333333;
}
```

**Runtime configuration** using application options:

```typescript
import { ApplicationOptions } from '@c8y/ngx-components';

export const options: ApplicationOptions = {
  brandingCssVars: {
    'brand-primary': '#1976d2',
    'navigator-bg-color': '#1565c0',
    'main-header-background-default': '#ffffff'
  }
};
```

#### Option 2: Branding Editor (No Code Required)

Use the **Branding Editor** in the Cumulocity Administration app to configure:
- Brand colors
- Logos
- Fonts
- Custom CSS

This provides a UI for customization without any code changes.

#### Option 3: SCSS Variables (Advanced)

For build-time customization with SCSS:

```scss
// Import with variable configuration
@use '~@c8y/style/variables' with (
  $use-relative-paths: true
);
```

> **Note:** SCSS uses a modern module system where variables are scoped and must be explicitly configured using `@use ... with` syntax.

### Variable Mapping Reference

| LESS (Deprecated) | CSS Custom Property | Description |
|-------------------|---------------------|-------------|
| `@brand-primary` | `--brand-primary` | Primary brand color |
| `@brand-complementary` | *deprecated* | Use `--brand-dark` or `--brand-light` instead |
| `@brand-dark` | `--brand-dark` | Dark brand color |
| `@navigator-bg-color` | `--navigator-bg-color` | Navigator background |
| `@navigator-text-color` | `--navigator-text-color` | Navigator text color |
| `@headerColor` | `--main-header-background-default` | Header background |
| `@header-text-color` | `--main-header-text-color-default` | Header text color |
| `@font-family-base` | `--font-family-base` | Base font family |

### Documentation & Resources

- [Branding Tokens](../../codex/content/design-system/design-tokens/branding-tokens.md) - Complete list of CSS custom properties
- [Application Styles](../../codex/content/common-tasks/application-styles.md) - Styling guide
- [c8y-design-tokens](https://github.com/Cumulocity-IoT/c8y-design-tokens) - Design tokens repository

---

## For Contributors: Technical Guide

This directory contains SCSS and LESS variable files. SCSS files use the SASS module system (`@use` and `@forward`), while LESS files are maintained for backward compatibility.

### Table of Contents

- [Directory Structure](#directory-structure)
- [Usage](#usage)
- [Variable Organization](#variable-organization)
- [Migration from LESS](#migration-from-less)
- [Adding New Variables](#adding-new-variables)
- [SCSS Module System](#scss-module-system)
- [Troubleshooting](#troubleshooting)

## Directory Structure

```
variables/
├── index.scss                    # SCSS main entry point - import this file
├── index.less                    # LESS main entry point (maintained for releases)
├── README.md                     # This file
│
├── dashboard-themes/             # Dashboard theme overrides
│   ├── _branded-dashboard.{scss,less}
│   ├── _dark-dashboard.{scss,less}
│   ├── _transparent-dashboard.{scss,less}
│   └── _white-dashboard.{scss,less}
│
├── tokens/                       # Design tokens from design system
│   ├── c8y-design-tokens.scss
│   └── c8y-design-tokens-dark.scss
│
└── [variable files]              # 34 paired SCSS/LESS files
    ├── _color-defaults.{scss,less}
    ├── _color-vars.{scss,less}
    ├── _components-vars.{scss,less}
    ├── _forms-vars.{scss,less}
    ├── _buttons-vars.{scss,less}
    ├── _alert-vars.{scss,less}
    ├── _badge-vars.{scss,less}
    ├── _typography-vars.{scss,less}
    ├── _layout-vars.{scss,less}
    └── ... (and 25 more paired files)
```

**Note:** Each variable file exists in both `.scss` and `.less` formats. SCSS files are used for builds; LESS files are maintained for backward compatibility.

## Usage

### Basic Import

To use variables in your SCSS file, import the main index:

```scss
@use "../../variables/index" as *;

.my-component {
  color: $brand-primary;
  padding: $size-16;
  background: $component-background-default;
}
```

### With Namespace (Recommended for Clarity)

```scss
@use "../../variables/index" as vars;

.my-component {
  color: vars.$brand-primary;
  padding: vars.$size-16;
}
```

### Configuring Variables

Some variable modules accept configuration:

```scss
@use "../../variables/index" with (
  $use-relative-paths: true
);
```

## Variable Organization

### Current Structure

Variables are organized in flat files with paired SCSS/LESS implementations:

- **_color-defaults.scss** - Default color palette
- **_color-vars.scss** - Semantic color mappings
- **_components-vars.scss** - Component-level variables
- **_forms-vars.scss** - Form-specific variables
- **_buttons-vars.scss** - Button-specific variables
- **_typography-vars.scss** - Font and text variables
- **_layout-vars.scss** - Grid and layout variables
- **_scaffolding.scss** - Base scaffolding with asset paths

### Variable Naming Convention

Variables follow the pattern:

```scss
// Component-based
$component-{property}-{variant}
$component-background-default
$component-border-width
$component-padding-base-horizontal

// Semantic colors
$brand-primary
$brand-dark
$brand-light

// Layout/spacing (size system)
$size-base          // 8px base unit
$size-8             // 8px
$size-16            // 16px
$size-24            // 24px
$size-32            // 32px

// Typography
$font-size-base
$font-size-small
$line-height-base
$font-family-base
```

## Migration from LESS

### Key Differences

| LESS | SCSS | Notes |
|------|------|-------|
| `@import` | `@use` / `@forward` | Module system with namespacing |
| `@variable` | `$variable` | Variable prefix changed |
| `.mixin()` | `@include mixin()` | Mixin calls |
| Lazy loading | Explicit dependencies | Must declare all imports |
| Guards `when` | `@if` / `@else` | Conditional logic changed |

### Variable Resolution

The `index.scss` file handles duplicate variables using `@forward hide`:

```scss
// Hide duplicate variables from color-vars
@forward '_color-vars' hide
  $component-background-default,
  $component-border-width,
  $component-border-style;
```

This prevents conflicts when multiple modules define the same variable.

### Removed Features

**LESS Guards** - SCSS doesn't support LESS-style conditional guards (`& when`). Code that depended on guards has been:
- Removed if it was legacy/deprecated behavior
- Converted to always-on if it's standard behavior
- Documented with instructions for custom override if needed

Example from `_navigator.scss`:
```scss
// LESS (conditional):
& when not(@appBranding='') {
  .c8y-icon { display: none !important; }
}

// SCSS (removed - document override path):
// To hide icons, add to your custom CSS:
// .navigator .title .c8y-icon { display: none !important; }
```

## LESS/SCSS Dual Maintenance

### Overview

Both LESS and SCSS files are maintained in this directory:

- **SCSS files**: Used for builds (primary)
- **LESS files**: Maintained for backward compatibility
- **Both must be kept in sync** to ensure consistency

### When Working with Variables

**Important**: When modifying variables, you must update both SCSS and LESS files:

1. **Make changes in SCSS file** (primary)

   ```scss
   // _buttons-vars.scss
   $btn-primary-bg: $brand-primary !default;
   ```

2. **Sync to LESS file** (convert syntax)

   ```less
   // _buttons-vars.less
   @btn-primary-bg: @brand-primary;
   ```

3. **Commit both files together**

   ```bash
   git add packages/style/variables/_buttons-vars.{scss,less}
   git commit -m "Update button variables"
   ```

### Syntax Quick Reference

| SCSS | LESS | Notes |
| ---- | ---- | ----- |
| `$variable` | `@variable` | Variable prefix |
| `@include mixin()` | `.mixin()` | Mixin calls |
| `@mixin name()` | `.name()` | Mixin definitions |
| `@use 'file'` | `@import 'file'` | Imports |
| `#{$var}` | `@{var}` | Interpolation |

### Pre-commit Hook

A pre-commit hook verifies LESS/SCSS sync:

- Detects SCSS changes
- Checks if corresponding LESS file is updated
- Compiles both preprocessors
- Blocks commit if compilation fails

## Adding New Variables

### 1. Choose the Right File

- **Component-specific** → Add to `_components-vars.scss`
- **Form-related** → Add to `_forms-vars.scss`
- **Color** → Add to `_color-vars.scss`
- **Layout/spacing** → Add to `_layout-vars.scss`
- **New category** → Create new file (see step 2)

### 2. Create a New Variable File

If creating a new category:

```scss
// variables/_my-new-vars.scss
@use 'color-defaults' as *;  // Import dependencies if needed

$my-variable: value !default;
$my-other-variable: $gray-60 !default;
```

### 3. Register in index.scss

Add your new file to `variables/index.scss`:

```scss
// Import and make available
@use '_my-new-vars' as *;
@forward '_my-new-vars';
```

Position matters! Place it after dependencies but before files that use it.

### 4. Use !default Flag

Always use `!default` for variables that should be customizable:

```scss
$my-variable: #007bff !default;  // ✅ Can be overridden
$my-constant: #007bff;           // ❌ Cannot be overridden
```

## SCSS Module System

### @use vs @import

**Never use `@import`** - it's deprecated and will be removed in Dart Sass 3.0.

```scss
// ❌ Old way (deprecated)
@import 'variables/index';

// ✅ New way
@use 'variables/index' as *;
```

### @use Rules

1. **Must be at the top** - No @use statements after regular CSS
2. **Each file once** - Can't @use the same file twice in one file
3. **Namespaced by default** - Use `as *` to add to global scope
4. **Private members** - Variables starting with `-` or `_` are private

### @forward for Re-exporting

The `index.scss` uses `@forward` to re-export all variables:

```scss
@use '_color-vars' as *;        // Make available in this file
@forward '_color-vars';         // Re-export for consumers
```

This allows a single import point: `@use 'variables/index' as *;`

### Configuration with 'with'

Pass configuration to modules:

```scss
@use '_scaffolding' with (
  $use-relative-paths: true
);
```

Note: Can't use both `with` and `as *` together. Use separately:

```scss
@use '_scaffolding' with ($use-relative-paths: true);  // Configure
@forward '_scaffolding' hide $use-relative-paths;      // Re-export but hide config var
```

## Troubleshooting

### "Undefined variable"

**Cause**: File doesn't import variables index.

**Solution**: Add to top of file:
```scss
@use "../../variables/index" as *;
```

### "This variable is available from multiple global modules"

**Cause**: Multiple modules define the same variable without hiding duplicates.

**Solution**: Use `@forward hide` in `index.scss`:
```scss
@forward '_color-vars' hide $duplicate-variable;
```

### "expected ';'"

**Cause**: Can't use `@use ... with (...) as *;`

**Solution**: Remove `as *`:
```scss
// ❌ Wrong
@use '_module' with ($var: value) as *;

// ✅ Right
@use '_module' with ($var: value);
@forward '_module';
```

### Circular dependency

**Cause**: File A imports B, B imports A.

**Solution**: Restructure to use a third file for shared variables, or use `@forward` instead of `@use` where appropriate.

### "The target selector was not found"

**Cause**: `@extend` references a class that doesn't exist or isn't loaded yet.

**Solution**: Add `!optional` flag:
```scss
@extend .some-class !optional;
```

## Best Practices

1. **Always import variables/index** - Don't import individual variable files
2. **Use semantic variable names** - Prefer `$component-background-default` over `$white`
3. **Document custom variables** - Add comments explaining usage
4. **Use !default for customization** - Allow variables to be overridden
5. **Avoid duplication** - Reuse existing variables when possible
6. **Namespace complex imports** - Use `as vars` for clarity in large files
7. **Keep variables DRY** - Define once, reference everywhere

## Related Documentation

- [SASS Module System](https://sass-lang.com/documentation/at-rules/use)
- [SASS @forward](https://sass-lang.com/documentation/at-rules/forward)
- [SASS Variables](https://sass-lang.com/documentation/variables)
- [Branding Tokens](../../codex/content/design-system/design-tokens/branding-tokens.md) - CSS custom properties
- [Application Styles](../../codex/content/common-tasks/application-styles.md) - Styling guide
