# Architecture Research

**Domain:** Hybrid Rust+webview GUI framework with cyberpunk aesthetic
**Researched:** 2026-02-25
**Confidence:** MEDIUM-HIGH

## System Overview

HoloHue is a **dual-layer framework**: a Rust crate that launches and manages a Tauri webview, and a bundled SolidJS frontend that renders all visual components, animations, and sounds. The Rust layer owns configuration, window lifecycle, and the public API. The web layer owns rendering, animation choreography, theming, and audio. Communication between layers uses Tauri's command/event IPC.

```
┌─────────────────────────────────────────────────────────────────────┐
│                     Consumer Application (Rust)                      │
│                                                                      │
│   use holohue::prelude::*;                                           │
│   HoloHue::builder().theme("neon-tokyo").soundscape(true).run()      │
│                                                                      │
├──────────────────────────────────────────────────────────────────────┤
│                     HoloHue Crate (lib.rs)                           │
│  ┌──────────────┐  ┌──────────────┐  ┌───────────────┐              │
│  │  App Builder  │  │ Theme Config │  │ Window Mgmt   │              │
│  │  (public API) │  │ (presets +   │  │ (constraints, │              │
│  │              │  │  custom)     │  │  defaults)    │              │
│  └──────┬───────┘  └──────┬───────┘  └──────┬────────┘              │
│         │                 │                  │                        │
│  ┌──────┴─────────────────┴──────────────────┴────────┐              │
│  │              Tauri Runtime Bridge                    │              │
│  │  - Commands (frontend calls Rust)                   │              │
│  │  - Events (Rust pushes to frontend)                 │              │
│  │  - Channels (streaming data)                        │              │
│  │  - State management (shared config)                 │              │
│  └──────────────────────┬─────────────────────────────┘              │
├─────────────────────────┼────────────────────────────────────────────┤
│                  WRY Webview (single window)                         │
│                         │                                            │
│  ┌──────────────────────┴──────────────────────────────────────┐     │
│  │                   SolidJS Frontend (bundled)                  │     │
│  │                                                               │     │
│  │  ┌────────────┐  ┌────────────┐  ┌────────────────────────┐  │     │
│  │  │  Animation  │  │  Soundscape│  │   Theme Engine         │  │     │
│  │  │  Choreo     │  │  Engine    │  │   (CSS custom props)   │  │     │
│  │  │  System     │  │  (Howler)  │  │                        │  │     │
│  │  └──────┬─────┘  └──────┬─────┘  └───────────┬────────────┘  │     │
│  │         │               │                     │               │     │
│  │  ┌──────┴───────────────┴─────────────────────┴────────────┐  │     │
│  │  │              Virtual Window Manager                      │  │     │
│  │  │  (DOM-based subwindows, NOT native multiwebview)         │  │     │
│  │  │  - Overlay panels                                        │  │     │
│  │  │  - Edge-docked panels                                    │  │     │
│  │  │  - Queued row/column layout                              │  │     │
│  │  │  - Draggable + resizable within constraints              │  │     │
│  │  └──────────────────────┬───────────────────────────────────┘  │     │
│  │                         │                                      │     │
│  │  ┌──────────────────────┴───────────────────────────────────┐  │     │
│  │  │              Component Library                            │  │     │
│  │  │  Buttons, Dropdowns, Panels, Inputs, Tables, Sliders...  │  │     │
│  │  │  (all with HoloHue styling, animation hooks, sound hooks)│  │     │
│  │  └──────────────────────────────────────────────────────────┘  │     │
│  └───────────────────────────────────────────────────────────────┘     │
└──────────────────────────────────────────────────────────────────────┘
```

### Critical Architecture Decision: DOM-Based Virtual Windows

Tauri's native multiwebview feature (behind the `unstable` flag) has significant unresolved bugs as of early 2026: broken positioning, rendering failures on load, layout errors on Linux, and resizing that stops working after window restore. Multiple open issues on the Tauri GitHub confirm this is not production-ready.

**Decision:** Implement the subwindow system entirely in the DOM/SolidJS layer as "virtual windows" -- styled div containers with drag/resize behavior, z-index management, and constraint enforcement. This is the same pattern used by web-based IDEs (VS Code's webview), the solidjs-window-manager library, and every successful web-based windowing system. It provides full control over the cyberpunk aesthetic (glow borders, angled corners, spawn animations) which would be impossible with native multiwebview anyway.

**Confidence:** HIGH -- verified via Tauri issue tracker and the inherent limitation that native webviews cannot render custom window chrome.

### Critical Architecture Decision: Crate Distribution Model

HoloHue distributes as a **Cargo workspace** with the primary `holohue` crate acting as the consumer-facing API. The crate embeds the pre-built SolidJS frontend assets at compile time using Tauri's asset embedding (`tauri-build`). Consumers never touch JavaScript -- they interact with a pure Rust API that configures and launches the framework.

The alternative (Tauri plugin model) was considered and rejected because HoloHue is not extending an existing Tauri app -- it IS the app shell. The plugin model is for adding features to someone else's Tauri app. HoloHue wraps Tauri entirely, exposing only a Rust builder API.

**Confidence:** MEDIUM -- the pattern of wrapping Tauri inside a library crate is not widely documented, but the Tauri crate's own API (Builder pattern, lib.rs entry point) directly supports this use case. The `tauri::Builder` is designed to be composed programmatically.

## Component Responsibilities

| Component | Responsibility | Typical Implementation |
|-----------|----------------|------------------------|
| **App Builder** (Rust) | Public API entry point. Accepts config (theme, soundscape, window constraints, custom commands). Launches Tauri runtime. | `HoloHue::builder().theme("neon-tokyo").run()` using Tauri's `Builder::default()` internally |
| **Theme Config** (Rust) | Stores preset themes and custom theme definitions. Validates theme tokens. Passes theme data to frontend on init. | Rust structs with serde serialization. Preset themes compiled into the crate. |
| **Window Constraints** (Rust) | Defines allowed subwindow positions, sizes, dock zones. Developer-facing config that constrains end-user rearrangement. | Constraint structs passed to frontend via Tauri state management. |
| **Tauri Runtime Bridge** (Rust) | Manages IPC between Rust config/state and SolidJS frontend. Registers commands, emits events, manages shared state. | `tauri::command` functions + event emission via `AppHandle::emit()` |
| **Animation Choreography System** (JS) | Defines and executes multi-step animation sequences. Manages animation timelines, stagger delays, and state-driven transitions. | Custom choreography engine built on solid-motionone (Motion One) + CSS animations for ambient effects |
| **Soundscape Engine** (JS) | Manages ambient background audio and UI interaction sounds. Supports categories (ambient, interaction, transition, notification) with independent volume. | Howler.js for audio playback. BleepsProvider-inspired pattern for declarative sound binding. |
| **Theme Engine** (JS) | Applies theme tokens as CSS custom properties. Manages theme switching with transition animations. | CSS custom property injection at `:root`. Design token architecture with primitive + semantic layers. |
| **Virtual Window Manager** (JS) | Manages subwindow lifecycle: creation, positioning, docking, z-ordering, resize, drag constraints. | SolidJS store-based state. DOM elements with pointer event handling. Constraint validation against Rust-provided rules. |
| **Component Library** (JS) | Pre-styled cyberpunk UI components. Each component integrates with animation system and sound system. | SolidJS functional components with `use:motion` directives and bleep hooks. |
| **Asset Bundler** (Build) | Compiles SolidJS frontend, embeds into Rust binary at build time. | `tauri-build` in build.rs. Vite builds frontend; output embedded as Tauri assets. |

## Recommended Project Structure

```
holohue/
├── Cargo.toml                    # Workspace root
├── crates/
│   ├── holohue/                  # Primary consumer-facing crate
│   │   ├── Cargo.toml
│   │   ├── src/
│   │   │   ├── lib.rs            # Public API: HoloHue::builder()
│   │   │   ├── builder.rs        # Builder pattern for app configuration
│   │   │   ├── theme/
│   │   │   │   ├── mod.rs        # Theme types + preset definitions
│   │   │   │   ├── presets.rs    # Built-in theme data (neon-tokyo, etc.)
│   │   │   │   └── tokens.rs    # Token type definitions
│   │   │   ├── window/
│   │   │   │   ├── mod.rs        # Window constraint types
│   │   │   │   └── layout.rs     # Layout constraint definitions
│   │   │   ├── sound/
│   │   │   │   └── mod.rs        # Sound config types (enable/disable, volumes)
│   │   │   └── commands/
│   │   │       ├── mod.rs        # Tauri command registrations
│   │   │       ├── theme.rs      # Theme switching commands
│   │   │       ├── window.rs     # Window management commands
│   │   │       └── sound.rs      # Sound control commands
│   │   └── build.rs              # tauri-build: embeds frontend assets
│   │
│   └── holohue-types/            # Shared types between Rust and TS
│       ├── Cargo.toml
│       └── src/
│           └── lib.rs            # Theme tokens, window constraints, events
│                                 # (serde + ts-rs for TS type generation)
│
├── frontend/                     # SolidJS application (NOT a crate)
│   ├── package.json
│   ├── vite.config.ts
│   ├── tsconfig.json
│   ├── src/
│   │   ├── index.tsx             # SolidJS entry point
│   │   ├── App.tsx               # Root component, theme provider, sound provider
│   │   ├── bridge/               # Tauri IPC integration
│   │   │   ├── commands.ts       # invoke() wrappers (auto-typed from holohue-types)
│   │   │   ├── events.ts         # Event listeners for Rust-pushed data
│   │   │   └── state.ts          # SolidJS stores synced with Rust state
│   │   ├── animation/            # Choreography system
│   │   │   ├── engine.ts         # Core choreography sequencer
│   │   │   ├── presets.ts        # Built-in sequences (spawn, click, transition)
│   │   │   ├── ambient.ts        # Breathing, ripple, splash ambient effects
│   │   │   └── types.ts          # Animation config types
│   │   ├── sound/                # Soundscape engine
│   │   │   ├── SoundProvider.tsx # Context provider for sound system
│   │   │   ├── engine.ts         # Howler.js wrapper, category management
│   │   │   ├── presets.ts        # Built-in sound mappings (click, hover, etc.)
│   │   │   ├── hooks.ts          # useBleep(), useAmbient() hooks
│   │   │   └── sprites/          # Audio sprite files
│   │   ├── theme/                # Theme engine
│   │   │   ├── ThemeProvider.tsx  # Applies CSS custom properties
│   │   │   ├── tokens.ts         # Token definitions matching Rust types
│   │   │   ├── presets/          # Built-in theme JSON files
│   │   │   └── transition.ts     # Theme switch animation
│   │   ├── windows/              # Virtual window manager
│   │   │   ├── WindowManager.tsx  # Root window management component
│   │   │   ├── Window.tsx         # Individual virtual window component
│   │   │   ├── store.ts          # Window state store (positions, z-order)
│   │   │   ├── constraints.ts    # Constraint enforcement logic
│   │   │   ├── dock.ts           # Edge-docking behavior
│   │   │   └── drag.ts           # Drag + resize handlers
│   │   ├── components/           # Component library
│   │   │   ├── Button.tsx
│   │   │   ├── Dropdown.tsx
│   │   │   ├── Panel.tsx
│   │   │   ├── TextInput.tsx
│   │   │   ├── Toggle.tsx
│   │   │   ├── Slider.tsx
│   │   │   ├── Table.tsx
│   │   │   ├── StatusBar.tsx
│   │   │   └── index.ts         # Barrel export
│   │   ├── layout/               # Layout primitives
│   │   │   ├── Grid.tsx
│   │   │   ├── SplitPane.tsx
│   │   │   └── ResizablePanel.tsx
│   │   └── styles/               # Global styles
│   │       ├── reset.css
│   │       ├── tokens.css        # CSS custom property definitions
│   │       ├── glow.css          # Glow line and neon effects
│   │       ├── scanlines.css     # Scanline overlay effect
│   │       └── animations.css    # Keyframe definitions
│   └── dist/                     # Build output (embedded by tauri-build)
│
├── demo/                         # Demo application (separate binary crate)
│   ├── Cargo.toml                # Depends on holohue crate
│   └── src/
│       └── main.rs               # Showcases all components and features
│
└── tauri.conf.json               # Tauri config (referenced by holohue crate)
```

### Structure Rationale

- **crates/holohue/:** The consumer-facing crate. Everything a Rust developer touches. The `lib.rs` exposes the builder API; internals handle Tauri bootstrap, command registration, and asset embedding. Consumers never see JavaScript.
- **crates/holohue-types/:** Shared type definitions serializable between Rust (serde) and TypeScript (ts-rs). Prevents drift between the Rust config API and the frontend's expectations. Small, dependency-light crate.
- **frontend/:** The SolidJS application that renders everything. This is an internal implementation detail -- consumers do not interact with it. It is pre-built during `cargo build` via `build.rs` and embedded into the binary.
- **demo/:** A separate binary crate that depends on `holohue` and demonstrates every feature. This is the v1 success metric.

## Architectural Patterns

### Pattern 1: Builder-Based Rust API

**What:** Consumers configure HoloHue through a Rust builder pattern that collects all options before launching the Tauri runtime. This hides all Tauri details behind an idiomatic Rust interface.

**When to use:** Always -- this is the primary consumer entry point.

**Trade-offs:** Pro: clean API, no Tauri knowledge required. Con: limits flexibility for advanced users who want raw Tauri access. Mitigation: expose an `escape hatch` method that provides the underlying `tauri::Builder` for advanced configuration.

**Example:**
```rust
use holohue::prelude::*;

fn main() {
    HoloHue::builder()
        .theme(Theme::NeonTokyo)
        .soundscape(SoundscapeConfig::default())
        .window_constraints(WindowConstraints {
            allow_overlay: true,
            allow_dock: vec![DockPosition::Left, DockPosition::Bottom],
            max_subwindows: 8,
            ..Default::default()
        })
        .on_ready(|ctx| {
            ctx.open_window("dashboard", WindowConfig::default());
        })
        .run();
}
```

### Pattern 2: Provider-Based Frontend Architecture

**What:** The SolidJS frontend uses nested context providers to supply theme, sound, animation, and window management capabilities to all components. Each system is independent but composable.

**When to use:** For all cross-cutting concerns (theme, sound, animation state).

**Trade-offs:** Pro: clean separation, components don't need to know about infrastructure. Con: deep provider nesting. Mitigation: compose providers into a single `<HoloHueProvider>` wrapper.

**Example:**
```tsx
// App.tsx -- internal, not consumer-facing
const App = () => (
  <ThemeProvider initial={config.theme}>
    <SoundProvider config={config.soundscape}>
      <AnimationProvider>
        <WindowManager constraints={config.windowConstraints}>
          <ApplicationShell />
        </WindowManager>
      </AnimationProvider>
    </SoundProvider>
  </ThemeProvider>
);
```

### Pattern 3: Choreography Sequences as Data

**What:** Animation sequences are defined as declarative data structures (arrays of steps with targets, properties, timing, and triggers), not imperative code. A choreography engine interprets these sequences at runtime.

**When to use:** For all multi-step animations (window spawn, page transitions, component enter/exit).

**Trade-offs:** Pro: sequences are serializable, reusable, composable, and can be defined in Rust config. Con: less flexible than raw imperative animation code for one-off effects. Mitigation: allow custom animation functions as escape hatches.

**Example:**
```typescript
// A window spawn choreography sequence
const windowSpawn: Sequence = {
  name: "window-spawn",
  steps: [
    { target: ".window-frame", animate: { scaleX: [0, 1], scaleY: [0, 1] },
      transition: { duration: 0.3, easing: "cubic-bezier(0.16, 1, 0.3, 1)" } },
    { target: ".glow-line", animate: { opacity: [0, 1], pathLength: [0, 1] },
      transition: { duration: 0.4, delay: 0.15 } },
    { target: ".window-content", animate: { opacity: [0, 1] },
      transition: { duration: 0.2, delay: 0.35 } },
    { sound: "window-open", at: 0 },
    { sound: "glow-hum", at: 0.15 },
  ]
};
```

### Pattern 4: CSS Custom Property Token Architecture

**What:** Theme values flow through a two-tier CSS custom property system: primitive tokens (raw color values) and semantic tokens (purpose-mapped references). Theme switching swaps primitive values; semantic tokens remain stable.

**When to use:** For all theming and visual customization.

**Trade-offs:** Pro: instant theme switching via CSS, no component re-renders, excellent performance. Con: CSS custom properties have string values only, no type safety at runtime. Mitigation: TypeScript types for token names, Rust types for token values, validated at build time.

**Example:**
```css
/* Primitive tokens -- swapped per theme */
:root[data-theme="neon-tokyo"] {
  --hh-color-primary-500: #00f0ff;
  --hh-color-accent-500: #ff2a6d;
  --hh-color-surface-base: rgba(10, 10, 15, 0.92);
  --hh-color-glow-primary: #00f0ff;
  --hh-anim-duration-fast: 150ms;
  --hh-anim-duration-normal: 300ms;
  --hh-anim-easing-enter: cubic-bezier(0.16, 1, 0.3, 1);
  --hh-glow-spread: 8px;
  --hh-glow-intensity: 0.6;
}

/* Semantic tokens -- stable across themes */
:root {
  --hh-button-bg: var(--hh-color-surface-base);
  --hh-button-border: var(--hh-color-primary-500);
  --hh-button-glow: var(--hh-color-glow-primary);
  --hh-window-border: var(--hh-color-primary-500);
  --hh-window-bg: var(--hh-color-surface-base);
}
```

### Pattern 5: Sound Categories with Declarative Binding

**What:** Sounds are organized into categories (ambient, interaction, transition, notification) with independent volume controls. Components declare which sounds they trigger via hooks, not imperative play calls.

**When to use:** For all UI sound effects and ambient audio.

**Trade-offs:** Pro: sounds are opt-out per category, volume is independently controllable, sound behavior is declarative and testable. Con: Howler.js adds ~10kb; audio sprites require build-time tooling. Mitigation: Howler.js is tree-shakeable and battle-tested; audio sprites can be pre-built.

**Example:**
```typescript
// Declarative sound binding in a component
const Button = (props) => {
  const { playBleep } = useBleep("click");

  return (
    <Motion.button
      animate={buttonAnimate}
      onPointerDown={() => playBleep()}
      onPointerEnter={() => playBleep("hover")}
      class="hh-button"
    >
      {props.children}
    </Motion.button>
  );
};
```

## Data Flow

### Initialization Flow

```
Consumer Rust Code
    |
    v
HoloHue::builder().theme(...).soundscape(...).run()
    |
    v
holohue::builder::build() --> Constructs tauri::Builder
    |                          - Registers commands
    |                          - Manages state (theme, constraints, sound config)
    |                          - Sets up event handlers
    v
Tauri Runtime launches webview
    |
    v
SolidJS app mounts --> index.tsx
    |
    v
Bridge layer calls invoke("get_initial_config")
    |                                        |
    v                                        v
Receives: theme preset, sound config,    Rust command handler
          window constraints, feature    reads managed state
          flags                          and returns serialized config
    |
    v
Providers initialize:
  ThemeProvider --> injects CSS custom properties on :root
  SoundProvider --> loads audio sprites via Howler.js
  AnimationProvider --> registers choreography presets
  WindowManager --> applies constraint rules
    |
    v
Application shell renders, ready for consumer content
```

### User Interaction Flow

```
User clicks a HoloHue Button
    |
    ├─> Sound: useBleep("click").play() --> Howler sprite plays "click" sound
    |
    ├─> Animation: Motion component triggers "button-click" choreography
    |   --> double blink glow (CSS animation via solid-motionone)
    |   --> glow fade (CSS custom property transition)
    |
    └─> If button has a Rust command handler:
        invoke("user_command", { args })
            |
            v
        Rust command executes
            |
            v
        Returns result to frontend via Promise
            |
            v
        UI updates reactively via SolidJS signals
```

### Theme Switch Flow

```
Developer or user triggers theme change
    |
    ├─> Frontend route:
    |   ThemeProvider.setTheme("vapor-grid")
    |       |
    |       ├─> Triggers theme-exit choreography (fade out glow, dim)
    |       ├─> Swaps CSS custom properties on :root[data-theme]
    |       ├─> Triggers theme-enter choreography (new glow sweep)
    |       └─> Notifies Rust via emit("theme-changed", { name })
    |
    └─> Rust route:
        invoke("set_theme", { name: "vapor-grid" })
            |
            v
        Rust validates theme name, updates managed state
            |
            v
        Emits "apply-theme" event to frontend
            |
            v
        Frontend ThemeProvider handles event (same as above)
```

### Window Management Flow

```
Developer calls ctx.open_window("panel-name", config)  [Rust]
    |
    v
Rust emits "open-window" event with window config
    |
    v
Frontend WindowManager receives event
    |
    ├─> Validates against constraints (max windows, allowed positions)
    |
    ├─> Creates virtual window entry in SolidJS store
    |   { id, component, position, size, dockZone, zIndex }
    |
    ├─> Triggers "window-spawn" choreography sequence
    |   (scale up + glow line sweep + content fade in + sound)
    |
    └─> Window renders as DOM element with:
        - Drag handler (constrained to allowed zones)
        - Resize handler (constrained to min/max sizes)
        - Z-index management (click to focus)
        - Close/minimize controls with exit animations
```

### Key Data Flows Summary

1. **Config down, events up:** Rust pushes configuration to the frontend at init and via events. The frontend sends user actions back to Rust via commands. This is a unidirectional-ish flow where Rust is the source of truth for configuration but the frontend is the source of truth for visual state.

2. **Theme tokens flow through CSS:** Theme data travels from Rust config -> serialized to frontend -> injected as CSS custom properties -> consumed by all components via `var()` references. No component re-renders needed for theme switches.

3. **Animation sequences are self-contained:** A choreography sequence contains all its timing, targets, and sound cues. The engine processes them sequentially. Components do not know about other components' animations.

4. **Sound is fire-and-forget:** Components trigger sounds via hooks. The sound engine handles sprite loading, category mixing, volume, and the global mute state. Components never manage audio state.

## Scaling Considerations

This is a desktop GUI framework, not a web service. "Scaling" means complexity scaling (more components, more windows, more animations) rather than user scaling.

| Scale | Architecture Adjustments |
|-------|--------------------------|
| Demo app (5-10 components) | Monolithic frontend, all components in one bundle. Simple choreography presets. No lazy loading needed. |
| Real dashboard (20-50 components) | Lazy-load window content via SolidJS `lazy()`. Audio sprites split by category to reduce initial load. Component library tree-shakes unused components. |
| Complex multi-panel app (50+ components, 10+ simultaneous windows) | Virtual window manager needs DOM recycling for off-screen windows. Animation engine needs priority queue (visible animations first). Consider Web Worker for sound mixing. |

### Scaling Priorities

1. **First bottleneck: Animation jank with many simultaneous windows.** The choreography engine must prioritize visible animations. Off-screen windows should skip animations entirely. Use `requestAnimationFrame` budgeting and the Web Animations API (via Motion One) which runs on the compositor thread, not the main thread.

2. **Second bottleneck: Memory from many open virtual windows.** Implement a "virtualized window" pattern: windows below the z-stack threshold or minimized have their DOM content unmounted (with state preserved in the store). Only visible windows maintain full DOM trees.

## Anti-Patterns

### Anti-Pattern 1: Native Multiwebview for Subwindows

**What people do:** Use Tauri's `unstable` multiwebview feature to create native subwindows for each panel.
**Why it's wrong:** The feature is unstable with known layout, rendering, and resize bugs (verified via Tauri GitHub issues #10420, #10011, #13071, #10131, #11376). Even if it stabilized, native webviews cannot render custom window chrome (angled corners, glow lines). Each webview is an isolated rendering context with no shared CSS/JS state.
**Do this instead:** DOM-based virtual windows within a single webview. Full control over styling, shared state, shared animation engine, shared sound engine.

### Anti-Pattern 2: Exposing Tauri Internals to Consumers

**What people do:** Let consumers of the holohue crate interact directly with `tauri::Builder`, `tauri::WebviewWindow`, or Tauri commands.
**Why it's wrong:** Couples consumers to Tauri's API, making it impossible to swap the underlying runtime later. Violates the "zero design effort" promise by requiring Tauri knowledge.
**Do this instead:** Wrap all Tauri interactions behind HoloHue's own types. Provide an `escape_hatch()` method for power users, but make the default path purely HoloHue types.

### Anti-Pattern 3: Imperative Animation Spaghetti

**What people do:** Each component manages its own animation timing with imperative `animate()` calls, leading to uncoordinated visual chaos.
**Why it's wrong:** Choreography requires coordination. If a window spawn animation, its glow effect, and its content fade all run independently, timing drift causes visual jank. Sound cues desync from visual events.
**Do this instead:** Choreography sequences as data (Pattern 3 above). The choreography engine is the single coordinator. Components register animation targets; the engine orchestrates timing.

### Anti-Pattern 4: JavaScript-Heavy Theme Logic

**What people do:** Implement theme switching by changing SolidJS state/props on every component, causing cascading re-renders.
**Why it's wrong:** In a framework with dozens of components across multiple virtual windows, re-rendering everything for a theme switch causes visible jank and missed animation frames.
**Do this instead:** CSS custom property architecture (Pattern 4 above). Theme switching is a single DOM operation (swap properties on `:root`). Browser handles propagation with zero JavaScript re-renders.

### Anti-Pattern 5: Tight Coupling Between Sound and Animation

**What people do:** Embed `playSound()` calls directly inside animation callbacks, creating brittle timing dependencies.
**Why it's wrong:** If sound is disabled (opt-out), animation callbacks throw or need null checks everywhere. Sound timing becomes impossible to adjust without modifying animation code.
**Do this instead:** Choreography sequences include sound cues as data (see Pattern 3). The engine routes sound cues to the sound system independently. If sound is disabled, cues are silently dropped.

## Integration Points

### Internal Boundaries

| Boundary | Communication | Notes |
|----------|---------------|-------|
| Rust crate <-> SolidJS frontend | Tauri IPC (commands + events) | Commands for request/response. Events for push notifications. Channels for streaming (future: live data feeds). All payloads are JSON-serialized via serde. |
| Theme Engine <-> Components | CSS custom properties | No direct coupling. Components use `var(--hh-*)` tokens. Theme engine sets values on `:root`. |
| Animation Engine <-> Components | Choreography registration | Components register animation targets via refs. Engine orchestrates sequences. Components do not call `animate()` directly for choreographed sequences. |
| Sound Engine <-> Components | Hooks (`useBleep`) | Components request sounds declaratively. Engine manages playback, sprites, volume, mute state. |
| Window Manager <-> Windows | SolidJS store + events | Manager owns the store of window states. Individual windows read from the store and dispatch actions (move, resize, close) back to it. |
| Rust Types <-> TS Types | `holohue-types` crate + `ts-rs` | Shared type definitions prevent drift. TypeScript types auto-generated from Rust structs during build. |

### External Dependencies

| Dependency | Role | Integration Pattern | Risk |
|------------|------|---------------------|------|
| Tauri v2 | Runtime, IPC, window creation, asset embedding | Wrapped entirely by holohue crate. Consumer never sees Tauri. | LOW -- mature, stable v2.4+ |
| SolidJS | UI rendering, reactivity | Internal frontend framework. Bundled into binary. | LOW -- stable, performant, small |
| solid-motionone | Animation primitives (Motion, Presence) | Used by choreography engine for WAAPI-based animations | LOW -- wraps standard Web Animations API |
| Howler.js | Audio playback, sprite management | Wrapped by SoundProvider. Consumer configures via Rust types. | LOW -- battle-tested, 14k+ GitHub stars |
| Vite | Frontend build tooling | Build step only. Produces assets for embedding. | LOW -- standard tooling |
| ts-rs | Rust-to-TypeScript type generation | Build step only. Generates `.ts` files from Rust structs. | LOW -- well-maintained, solves a real problem |

## Build Order (Dependencies Between Components)

This ordering reflects what must exist before the next layer can be built. Each phase builds on the previous.

```
Phase 1: Foundation
  ├── holohue-types crate (shared types)
  ├── Tauri project scaffold with asset embedding
  ├── Builder pattern API (Rust side)
  └── SolidJS project with Vite, basic bridge layer

Phase 2: Theme System
  ├── CSS custom property token architecture
  ├── ThemeProvider component
  ├── 2-3 preset themes (enough to prove switching works)
  └── Rust theme config types + command

Phase 3: Component Library (Core)
  ├── Window chrome (the angled/notched frame + glow line)
  ├── Button, Panel, TextInput (minimum viable components)
  └── Components consume theme tokens

Phase 4: Animation System
  ├── Choreography engine (sequence interpreter)
  ├── Animation presets (window spawn, button click, transitions)
  ├── Components integrate with animation hooks
  └── Ambient effects (breathing, ripple)

Phase 5: Virtual Window Manager
  ├── Window store + constraint system
  ├── Drag + resize + z-index management
  ├── Dock zones (edge-docked, overlay, queued)
  └── Window lifecycle animations (via choreography engine)

Phase 6: Sound System
  ├── Howler.js integration + SoundProvider
  ├── Audio sprite build pipeline
  ├── Sound presets (click, hover, transition, error, ambient)
  └── Choreography sequences gain sound cues

Phase 7: Full Component Library + Demo
  ├── Remaining components (Dropdown, Toggle, Slider, Table, StatusBar)
  ├── Layout primitives (Grid, SplitPane, ResizablePanel)
  └── Demo application showcasing everything
```

**Ordering rationale:**
- Types and scaffolding first because everything depends on them.
- Theme system before components because components consume theme tokens -- building components without tokens means reworking them later.
- Core components before animation because animation targets need to exist as DOM elements first. You cannot choreograph elements that do not yet exist.
- Animation before window manager because window spawn/close uses choreography sequences.
- Sound after animation because sound cues are embedded in choreography sequences -- the sequence format must be stable before adding sound triggers.
- Full component library last because it depends on all infrastructure being in place.

## Sources

- [Tauri v2 Architecture](https://v2.tauri.app/concept/architecture/) -- HIGH confidence, official documentation
- [Tauri v2 Calling Rust from Frontend](https://v2.tauri.app/develop/calling-rust/) -- HIGH confidence, official documentation
- [Tauri v2 Calling Frontend from Rust](https://v2.tauri.app/develop/calling-frontend/) -- HIGH confidence, official documentation
- [Tauri v2 Plugin Development](https://v2.tauri.app/develop/plugins/) -- HIGH confidence, official documentation
- [Tauri Multiwebview Issues](https://github.com/tauri-apps/tauri/issues/10420) -- HIGH confidence, verified bug reports (#10420, #10011, #13071, #10131, #11376)
- [Arwes Sci-Fi UI Framework](https://arwes.dev/docs) -- MEDIUM confidence, alpha-stage project but validates architectural patterns for sci-fi UI
- [Arwes Animation System](https://version1-breakpoint1.arwes.dev/docs/animation-system) -- MEDIUM confidence, v1 docs (current version is different architecture)
- [Arwes React Bleeps](https://next.arwes.dev/docs/develop/react/bleeps) -- MEDIUM confidence, next-branch docs
- [solid-motionone](https://github.com/solidjs-community/solid-motionone) -- HIGH confidence, GitHub source + DeepWiki analysis
- [solidjs-window-manager](https://github.com/AndreiTelteu/solidjs-window-manager) -- MEDIUM confidence, community library validates pattern
- [Howler.js](https://howlerjs.com/) -- HIGH confidence, established library (14k+ stars)
- [CyberCore CSS](https://dev.to/sebyx07/introducing-cybercore-css-a-cyberpunk-design-framework-for-futuristic-uis-2e6c) -- MEDIUM confidence, validates cyberpunk CSS patterns
- [Motion Design Tokens](https://medium.com/@ogonzal87/animation-motion-design-tokens-8cf67ffa36e9) -- MEDIUM confidence, establishes animation token pattern
- [Cargo Workspaces](https://doc.rust-lang.org/book/ch14-03-cargo-workspaces.html) -- HIGH confidence, official Rust documentation

---
*Architecture research for: HoloHue -- hybrid Rust+webview cyberpunk GUI framework*
*Researched: 2026-02-25*
