# ARCHITECTURE.md
## 1. System Overview
Magma is a monorepo managed with NX and npm workspaces. It is composed of five independent sub-projects, each published as a separate npm package under the `@maggioli-design-system` scope. Sub-projects have a strict one-directional dependency graph: no circular dependencies are allowed.
```mermaid
graph TD
DT["@maggioli-design-system/design-tokens"]
ID["@maggioli-design-system/identity"]
IC["@maggioli-design-system/icons-svg"]
ST["@maggioli-design-system/styles"]
WC["@maggioli-design-system/magma (stencil)"]
DT --> ST
ST --> WC
IC --> WC
ID --> WC
```
**Required build order**: `design-tokens` → `styles` → `icons` → `stencil`
---
## 2. Sub-projects
### 2.1 `design-tokens`
Generates design tokens for colors, typography, spacing, borders and other platform-agnostic values.
- Built on **Adobe Leonardo** (color palette generation with WCAG contrast ratios) and **Style Dictionary** (token transformation and output)
- Outputs tokens in multiple formats: CSS custom properties, Tailwind 4 theme, Flutter/Dart, JSON
- Color palette categories: `tone` (neutrals), `status` (info/success/warning/error), `label` (semantic accent colors), `variant` (primary/secondary/ai), `brand`
- Token levels: **primitive** (raw values) → **semantic** (role-based) → **component** (component-scoped CSS vars)
- Exposes a CLI (`npx magma-design-tokens`) to generate custom palettes from a config file
Key output files consumed by other sub-projects:
```
dist/css/colors-rgb-*.css # RGB color vars (required by Tailwind and web components)
dist/css/colors-hex-*.css # HEX color vars (plain CSS usage)
dist/css/tailwind-theme-color.css
dist/css/tailwind-theme-typography.css
```
### 2.2 `identity`
Static brand assets: logos, avatars, and brand imagery for all Maggioli Group products. Read-only from consumer projects — never modify these assets directly.
Asset categories:
- `resources/brand/` — logos per brand (gruppo-maggioli, maggioli-editore, rnd, magma)
- `resources/avatar/` — avatar illustrations per brand
### 2.3 `svg-icons`
The full SVG icon library. Icons are referenced by filename slug inside components via the `icon` prop. The `mds-icon` component fetches them at runtime from a path configured via `sessionStorage`.
```javascript
// Required setup in every consumer application
window.sessionStorage.setItem('mdsIconSvgPath', 'assets/img/svg/');
```
Icons follow a semantic slug naming convention (e.g. `action-email-send`, `status-warning`). See `projects/svg-icons/svg/` for the full list.
### 2.4 `styles`
CSS and Tailwind 4 styles consumed by the web component library and consumer applications.
| Output file | Purpose |
|---|---|
| `dist/css/globals.css` | Global CSS custom properties (`--magma-*` design decisions) |
| `dist/css/reset.css` | Opinionated CSS reset |
| `dist/css/colors-rgb-*.css` | RGB color tokens (required for Tailwind and web components) |
| `dist/css/hydrated.css` | FOUC prevention for StencilJS |
| `dist/css/animations.css` | Shared animations |
| `dist/tailwind/` | Tailwind 4 layers: base, typography, utilities |
CSS cascade layer order (consumer apps must respect this):
```
reset → vendor → theme → base → components → utilities → overrides
```
Dark mode is handled via palette-level CSS custom properties. Activation classes on ``:
- `dark-mode` — manual dark mode
- `system-mode` — follows OS preference
- `pref-theme-scheme-dark / light / all` — fine-grained control
Global design decisions overridable via CSS custom properties on `:root`:
- `data-corner-shape` — corner geometry: the shape AND the `--magma-radius-*` scale tuned for it,
moved together (default: `squircle`, on a bare `:root`). Works on any element, so a subtree can
deviate. `--magma-corner-shape` alone changes the shape WITHOUT the scale
- `--magma-disabled-opacity` — default: `0.5`
- `--magma-outline-focus` — focus ring style
- Z-index scale: header `1000` → notification `2000` → modal `3000` → backdrop `4000` → dropdown `5000` → tooltip `6000` → theme-overlay `7000` → context-menu `8000`
### 2.5 `stencil`
The web component library. ~115 components built with StencilJS, compiled to standard Custom Elements. Also outputs framework-specific wrappers:
- `@maggioli-design-system/magma` — vanilla JS / HTML
- `@maggioli-design-system/magma-react` — React wrapper
- `@maggioli-design-system/magma-angular` — Angular wrapper
The wrappers are separate npm workspaces, `projects/stencil-react` and `projects/stencil-angular` (nx projects of the same name), siblings of `projects/stencil`. The Stencil build generates their sources (`projects/stencil-react/src`, `projects/stencil-angular/magma-angular/src/stencil-generated`) and their agent install docs; they only compile what `stencil` emitted. They live outside `projects/stencil` because npm never materializes the `node_modules` of a workspace nested inside another workspace (#666, #672).
---
## 3. Component Architecture
### 3.1 Shadow DOM vs Scoped
Most components use `shadow: true` (full Shadow DOM encapsulation). Form-associated components (e.g. `mds-input`, `mds-input-select`) use `scoped: true` so the native `` participates in form submission natively.
### 3.2 Component categories
| Category | Description | Examples |
|---|---|---|
| **Primitive** | Atomic building blocks, used internally by other components | `mds-text`, `mds-icon`, `mds-spinner` |
| **Atom** | Single-purpose UI element | `mds-button`, `mds-badge`, `mds-avatar` |
| **Molecule** | Composed of atoms, single concern | `mds-input`, `mds-chip`, `mds-breadcrumb` |
| **Compound** | Parent + required child component pair | `mds-accordion` + `mds-accordion-item`, `mds-card` + `mds-card-header/content/footer/media` |
| **Organism** | Complex layout component | `mds-table`, `mds-modal`, `mds-header` |
| **Preference** | User preference controls (theme, contrast, animation) | `mds-pref`, `mds-pref-theme`, `mds-pref-contrast` |
### 3.3 Compound component pattern
Several components work exclusively as parent/child pairs. The child must always be a direct slot child of the parent:
```html
............
...
```
### 3.4 Tone system
Components that carry visual weight expose both a `variant` (color role) and a `tone` (visual intensity) prop. These two axes are independent:
| Tone | Description |
|---|---|
| `strong` | Filled, high contrast (default) |
| `weak` | Tinted background, lower contrast |
| `outline` | Border only, transparent background |
| `text` | No background or border, text-only |
> ⚠️ Magma 2.0 breaking rename: `ghost` → `outline`, `quiet` → `text`. Old names are not supported.
### 3.5 CSS custom properties per component
Every component exposes scoped CSS custom properties for controlled overrides (e.g. `--mds-button-radius`, `--mds-button-background`). These are the **only supported way** to style components from the outside. Never write CSS that targets internal shadow DOM nodes directly.
---
## 4. Token Flow
```mermaid
graph LR
A["Adobe Leonardo\n(palette generation)"] --> B["Style Dictionary\n(transformation)"]
B --> C["CSS RGB vars\n--tone-neutral-01"]
B --> D["Tailwind 4 theme\n@theme { --color-tone-neutral }"]
C --> E["Web components\ninternal CSS"]
D --> F["Consumer apps\nTailwind utility classes"]
```
Color values in CSS must always use the RGB format with the `rgb()` wrapper:
```css
/* correct — supports opacity modifiers */
color: rgb(var(--tone-neutral-03));
/* incorrect — hex vars cannot be used with opacity */
color: var(--tone-neutral-03);
```
---
## 5. Consumer Application Setup
Installing Magma into a consumer application (styles, fonts, icons, and component
registration for plain web components / React / Angular) is documented in its own
canonical set of specs:
- `docs/agents/SPEC.md` - entry point: pick a target, version compatibility matrix
- `docs/agents/assets.md` - shared asset setup (styles import order, fonts, icons, identity)
- `docs/agents/web-components.md`, `docs/agents/react.md`, `docs/agents/angular.md` - per-target install tracks
- `docs/agents/usage.md` - using components after install: conventions + app-level styling
Do not duplicate import lists here - `docs/agents/assets.md` is the single source of
truth for the required CSS imports and cascade-layer order.