Architecture

FrontAlign is designed as a UI engine, not only as a collection of styles or standalone JavaScript widgets.

Its architecture is built around a simple separation of responsibility: the CSS foundation owns visual structure, design tokens, utilities, components, responsive behavior, and theme variables; the JavaScript runtime owns interaction, lifecycle control, lazy initialization, dynamic DOM handling, and component APIs.

This separation keeps static interfaces CSS-first, while allowing interactive interfaces to initialize only when behavior is actually needed.

System Overview

FrontAlign is organized into three main layers.

LayerResponsibilityPrimary output

CSS Foundation

Defines tokens, base styles, layout primitives, utilities, responsive helpers, forms, typography, surfaces, components, and dark mode variables.

Stable class system and theme-aware visual language.

JavaScript Runtime

Registers delegated components, observes lazy components, handles lazy images, watches dynamic DOM changes, and exposes component APIs.

Predictable browser behavior with cleanup support.

Compiler & JIT Engine

Processes project configuration, design tokens, custom fonts, custom classes, scan targets, safelists, and optimized production output.

Generated project CSS for application workflows.

The core runtime can be used directly in the browser through CDN builds or inside application workflows through NPM. The class system and component behavior remain consistent across both setups.

CSS Foundation

The CSS foundation provides the visual contract of FrontAlign. It defines the base design language before any JavaScript behavior is involved.

At the root level, FrontAlign exposes color palettes, semantic tokens, spacing, radius, shadows, typography, surface variables, form variables, button variables, grid templates, transition settings, and dark mode overrides.

:root {
  --primary: var(--blue-600);
  --primary-contrast: var(--white);
  --danger: var(--red-500);
  --danger-contrast: var(--white);
  --success: var(--green-500);
  --success-contrast: var(--white);
  --warning: var(--yellow-500);
  --warning-contrast: var(--dark);
  --info: var(--teal-600);
  --info-contrast: var(--white);
  --muted: var(--slate-500);
  --white: oklch(1 0 0);
  --light: oklch(0.961 0 0);
  --dark: oklch(0.2 0.01 260);
  --accent: oklch(
    from var(--primary) min(calc(l + 0.08), 0.88) calc(c * 0.9) h
  );
  --accent-contrast: var(--white);
  --space-sm: 0.5rem;
  --space-md: 1rem;
  --space-lg: 1.5rem;
  --radius-2: 0.5rem;
  --radius-4: 1rem;
  --radius-pill: 9999px;
}

Dark mode is handled through the fa-theme attribute. Instead of requiring a separate stylesheet, the same semantic tokens are redefined for dark surfaces.

[fa-theme="dark"] {
  --primary: var(--blue-300);
  --primary-contrast: var(--dark);
  --danger: var(--red-300);
  --danger-contrast: var(--dark);
  --success: var(--green-400);
  --success-contrast: var(--dark);
  --warning: var(--yellow-400);
  --warning-contrast: var(--dark);
  --info: var(--teal-300);
  --info-contrast: var(--dark);
  --accent: oklch(
    from var(--primary) min(calc(l + 0.06), 0.9) calc(c * 0.85) h
  );
  --accent-contrast: var(--dark);
  --muted: var(--slate-400);
}

This makes components and utilities theme-aware by default. A button, form control, table, modal, drawer, tooltip, toast, or navbar can use semantic variables without needing a separate dark-mode implementation.

Utility System

FrontAlign includes utility classes for common interface work: display, positioning, spacing, width, height, flexbox, grid, gap, order, overflow, overscroll, object fit, text behavior, line height, font weight, transforms, shadows, borders, colors, opacity, selection, and responsive visibility.

The utilities are intentionally readable and component-friendly.

<section class="container is-grid md:grid-cols-2 gap-4 align-items-center">
  <div>
    <h1>Build with structure.</h1>
    <p class="text-muted">
      Ship with predictable utilities and reusable components.
    </p>
  </div>

  <div class="is-flex justify-content-end">
    <button class="button is-primary">Get Started</button>
  </div>
</section>

The utility layer is not separate from the component layer. Both use the same token system, responsive model, theme variables, and naming conventions.

Component Styling

FrontAlign components are styled through normal HTML classes and semantic variables. The CSS layer defines the visual state, while the runtime only controls behavior when required.

Examples include:

Component groupExamples

Navigation

Navbar, nav, dropdown, breadcrumb, pagination.

Feedback

Alert, toast, badge, progress, spinner, tooltip.

Overlay

Modal, drawer, backdrop-driven interactions, scroll locking.

Content

Accordion, collapse, skeleton , carousel, swiper, listview, tableview, blockquote.

Forms

Inputs, selects, textareas, input groups, validation states, custom select behavior.

The result is a component model where static markup is useful on its own, and JavaScript is added only for interaction.

Runtime Model

The JavaScript runtime is centered around the FrontAlign class.

When a runtime instance is created, FrontAlign applies runtime configuration, registers delegated components, observes lazy components, observes lazy images, and starts watching the DOM for dynamically inserted elements.

const fa = new FrontAlign();

The runtime uses two categories of components.

Runtime categoryHow it worksExamples

Delegated

Registered once at the document level. Events are handled through delegation, so existing and matching future elements can work without per-element setup.

Accordion, navbar, collapse, alert, dropdown, drawer, form.

Auto-loaded

Observed through the viewport and initialized when the element becomes relevant.

Swiper, badge, tabview , toast , popover , lazyimage , range

This hybrid model avoids unnecessary initialization while keeping interactive markup simple.

Delegated Components

Delegated components attach a small number of global listeners instead of binding behavior to every matching element individually.

A navbar toggle, dropdown trigger, collapse trigger, alert close button, drawer trigger, accordion item, or form behavior can be handled from a shared listener.

<button class="navbar-toggler" fa-toggle="navbar" data-target="#main-menu">
  Menu
</button>

<div id="main-menu" class="navbar-menu">
  <a href="/docs">Docs</a>
  <a href="/components">Components</a>
</div>

This approach has three advantages:

  • Less repeated JavaScript work per element.
  • Better support for content added after page load.
  • Cleaner cleanup because each delegated module returns a disposer function.

Lazy Components

Some components do not need to initialize immediately. FrontAlign observes auto-loaded components and initializes them when they enter the viewport.

<div fa-component="swiper" class="swiper">
  <div class="swiper-wrapper">
    <article class="card">...</article>
    <article class="card">...</article>
    <article class="card">...</article>
  </div>
</div>

The runtime uses IntersectionObserver for lazy component initialization. When an observed component becomes visible, the related initializer runs once and the element is marked as loaded internally.

Lazy images follow the same idea through img[data-src].

<img
  data-src="/images/product.jpg"
  alt="Product preview"
/>

This allows image loading and component behavior to stay lightweight on pages with many interactive sections.

Dynamic DOM Handling

FrontAlign also watches for elements added after the initial page load.

The runtime uses MutationObserver to detect new nodes. If a new node or one of its children contains fa-component, FrontAlign checks whether that component belongs to the auto-loaded group and starts observing it. Newly inserted lazy images are handled the same way.

This is useful for:

  • client-rendered sections,
  • CMS-injected content,
  • tabs or drawers that mount content later,
  • partial page updates,
  • framework-driven DOM changes.

The goal is not to replace a framework lifecycle. The goal is to keep FrontAlign behavior predictable when the DOM changes after initialization.

DOM Contract

FrontAlign uses HTML attributes as the contract between markup and runtime behavior.

PatternPurposeExample
fa-componentMarks a component that can be initialized by the runtime.fa-component="accordion"
fa-toggleMarks a trigger that controls a behavior through delegation.fa-toggle="collapse"
data-*Provides optional behavior configuration in markup.data-target="#navbar-menu"
State classesRepresent visual and behavioral state.

is-active, is-hidden, is-visible

This keeps the API readable in plain HTML and predictable inside frameworks.

Lifecycle Events

FrontAlign components dispatch lifecycle events for key interactive actions. These events allow advanced behavior without modifying the component internals.

const panel = document.querySelector("#details");

panel.addEventListener("fa.collapse.open", (event) => {
  // Runs before the panel opens.
  // Call event.preventDefault() to cancel the action.
});

panel.addEventListener("fa.collapse.opened", (event) => {
  // Runs after the panel has opened.
});

Several components follow this pattern with cancelable "before" events and non-cancelable "after" events.

ComponentExample events

Collapse

fa.collapse.open, fa.collapse.opened, fa.collapse.close, fa.collapse.closed

Drawer

fa.drawer.open, fa.drawer.opened, fa.drawer.close, fa.drawer.closed

Accordion

fa.accordion.open, fa.accordion.opened, fa.accordion.close, fa.accordion.closed

Alert

fa.alert.close, fa.alert.closed

Use lifecycle events when you need to coordinate analytics, custom validation, conditional blocking, external state, or additional UI updates.

Accessibility Behavior

FrontAlign keeps accessibility close to component behavior instead of treating it as a separate layer.

The runtime updates relevant interaction state where needed, such as aria-expanded for collapse-style controls. Generated feedback components use live-region semantics where appropriate, such as toast notifications with role="status" and aria-live="polite".

Overlay-style components also include behavior that users expect from interactive UI systems, including Escape-key handling, backdrop interactions, focus-oriented flows, and scroll locking where applicable.

Accessibility still depends on correct markup. FrontAlign can manage runtime state, but headings, labels, alt text, button semantics, and meaningful document structure should come from the application.

Scroll Locking and Overlays

Overlay components require more than a visible panel. They also need to safely prevent background scrolling without causing layout shifts.

FrontAlign includes an internal scroll locking system that automatically manages body locking, scroll position preservation, scrollbar compensation, and layout stability.

Components such as drawers, modals, and other overlay-based interfaces use this behavior automatically when background scrolling needs to be disabled.

No additional configuration is required. Scroll locking is enabled by default and handled internally by the framework.

The CSS layer owns the visual states. The runtime owns opening, closing, scroll lock, Escape handling, and cleanup.

Instance APIs

The runtime also exposes instance methods for creating or controlling components directly from JavaScript.

const fa = new FrontAlign();

fa.carousel.create("#hero-carousel", { loop: true });

fa.modal.alert("default", {
  heading: "Welcome",
  content: "FrontAlign is ready.",
});

fa.toast.show({
  message: "Saved successfully.",
  status: "success",
});

Use instance APIs when a component needs to be created from application logic instead of static markup.

Cleanup Contract

FrontAlign is designed to be initialized and disposed predictably.

The runtime stores disposer functions for delegated modules, disconnects IntersectionObserver, disconnects MutationObserver, clears delegated handlers, and calls component-specific disposers for auto-loaded components when available.

const fa = new FrontAlign();

// Later, when the runtime is no longer needed:
fa.dispose();

This is especially important in environments where pages or layouts can be mounted and unmounted without a full browser reload.

Configuration Boundary

FrontAlign has two configuration paths.

EnvironmentConfiguration modelUse when

CDN

Pass runtime configuration directly when creating the FrontAlign instance.

You want browser-first usage without a build step.

NPM

Use fa.config.js and the Compiler & JIT Engine.

You need project-level tokens, custom classes, fonts, scan targets, safelists, and production output.

Architecture explains how the layers work together. The Compiler Engine guide explains how project configuration is processed into generated CSS.

Design Principles

FrontAlign follows a few architectural rules.

PrincipleMeaning

CSS-first by default

Static UI should work through tokens, utilities, and component classes before JavaScript is needed.

Runtime only where useful

Interactive behavior is initialized through delegation, observation, or explicit APIs instead of attaching unnecessary work everywhere.

Same contract everywhere

The same classes, attributes, tokens, and state conventions are used across CDN, NPM, and framework workflows.

Predictable cleanup

Observers, listeners, component instances, and runtime state should be removable when the runtime is no longer needed.

These rules are what make FrontAlign feel like one engine instead of separate CSS, JavaScript, and framework utilities.

Continue Reading

GuideWhat it covers

Compiler Engine

Project configuration, token generation, custom fonts, custom classes, scan targets, safelists, and optimized CSS output.

React Integration

Provider setup, hooks, runtime helpers, delegated behavior, and Next.js usage.

Browser Support

Supported browsers, modern CSS features, runtime APIs, and compatibility expectations.

FrontAlign