# eQuantic.UI Styling Architecture
## Core Philosophy
**eQuantic.UI** provides a **Flutter-inspired** developer experience (DX) while leveraging the full
power of each rendering target. The styling architecture is built on three pillars:
1. **Abstraction**: Components author _what_ to style — typed C# values, never CSS strings.
2. **One semantics, two targets**: the same style vocabulary drives dp values on native (Photon) and CSS on the web.
3. **Performance**: build-time class generation and deduplication — no CSS-in-JS runtime overhead.
---
## 1. Styling Components — Typed C#, No CSS Plane
Component styling is authored entirely in typed C# (`BoxStyle`, `StyleDiff`, design tokens) and
lowered by the **atomic style engine**: every regular declaration becomes ONE deduplicated atomic
class, byte-identical between SSR (C#) and hydration (TS); theme colors reference
`var(--eq-color-*)` custom properties. Hover/focus states, window-size-class adaptivity, sticky
positioning and transforms are all part of the vocabulary — zero JavaScript involved.
### The code face
A monospaced run (`Text` with `Mono`, a rich run, a `CodeBlock`) draws in a stack the framework
owns, and it lands on an **atomic class** — which beats a `body { font-family }` rule, and whose
name is a content hash that moves between builds. So there was nowhere to hang your own code face.
The hook is a variable:
```css
:root { --eq-font-mono: 'JetBrains Mono', ui-monospace, monospace; }
```
Every mono run follows it, with the platform stack as the fallback when nothing sets it.
The **measurer reads the same variable**, and that is not an implementation detail you can ignore
if you ship a code editor: `CodeEditor` places its caret from a measured column advance, so
measuring in one face while drawing in another puts the caret beside the character it is on rather
than under it.
The full engine — laws, pseudo-states, size classes, the generated stylesheet — is documented in
[DesignSystem](DesignSystem). The abstract vocabulary itself (`Box`, `Row`/`Column`, `Grid`,
`Stack`, …) is documented in [Write-Once Components](WriteOnceComponents).
### Theming = providing an `IAppTheme`
Themes are typed C# too — colors as light/dark `ColorToken` pairs, type roles, shape scale,
elevation — selected in one line and bridged SSR→client:
```csharp
builder.Services.AddUI(options =>
{
options.ScanAssembly(typeof(Program).Assembly)
.UseTheme(PhotonTheme.Instance); // or MaterialTheme.FromSeed(color)
});
```
Two implementations ship: **PhotonTheme** (the default) and **MaterialTheme** (real Material 3,
including dynamic color from a seed). Swap the theme and every component rebrands — server and
client, web and native. Runtime light/dark switching is a service (`IThemeController`); see
[DesignSystem](DesignSystem).
---
## 2. The HTML Escape Hatch
The low-level web layer (`eQuantic.UI.Core`) mirrors the DOM 1:1. Every `HtmlElement` exposes the
attributes the browser has:
```csharp
public abstract class HtmlElement : IComponent {
/// Raw CSS classes (space-separated).
public string? ClassName { get; set; }
/// Inline styles for dynamic values (e.g., coordinates, colors from DB).
public HtmlStyle? Style { get; set; }
}
```
This contract means the web layer **does not enforce any CSS framework** — it renders HTML
attributes. `DynamicElement` goes further and renders any tag with any attributes. Standard CSS
classes from any stylesheet work natively:
```csharp
new DynamicElement("aside") { ClassName = "my-sidebar" }
```
---
## 3. Bringing external CSS
The framework ships exactly **one** styling engine — the typed C# pipeline above. There is no
bundled CSS framework and no adapter layer: a page that needs hand-written markup uses the escape
hatch (`HtmlElement`/`DynamicElement` + `ClassName`), and any stylesheet the app brings — its own
CSS file, a utility framework it builds itself — is referenced like on any web project:
```csharp
builder.Services.AddUI(options =>
{
options.ConfigureHtmlShell(shell => shell.AddStylesheet("/css/app.css"));
});
```
The framework neither generates nor processes that CSS; it is the app's own build concern.
## 4. Package Roles
| Package | Purpose |
| :----------------------- | :----------------------------------------------------------------------------- |
| **eQuantic.UI.Primitives** | Typed styles, design tokens, the abstract vocabulary — the styling source of truth. |
| **eQuantic.UI.Core** | The DOM-mirror layer: `HtmlElement`, `ClassName`, `HtmlStyle`, `DynamicElement`. |
| **eQuantic.UI.Web** | The web realizer + atomic style engine (`StyleAtomizer`) + generated stylesheet. |