# 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. |