# Pitfalls Research

**Domain:** Hybrid Rust+webview GUI framework with cyberpunk aesthetic, animations, audio, and subwindow system
**Researched:** 2026-02-25
**Confidence:** MEDIUM-HIGH (multiple verified sources across Tauri, Rust audio, CSS animation, and crate distribution domains)

## Critical Pitfalls

### Pitfall 1: Cross-Platform Webview Rendering Inconsistencies

**What goes wrong:**
Tauri uses the system's native webview -- WebView2 (Chromium-based) on Windows, WKWebView (WebKit) on macOS, and WebKitGTK (WebKit) on Linux. These are fundamentally different rendering engines. CSS that looks pixel-perfect on Windows may render differently on macOS/Linux: font metrics shift, box-shadow blur radii compute differently, sub-pixel anti-aliasing varies, and filter effects behave inconsistently. For a framework whose entire value proposition is a specific visual aesthetic (cyberpunk glow lines, neon effects, angled corners), cross-platform visual fidelity is existential.

**Why it happens:**
Developers build and test on one platform (usually their daily driver), then discover rendering differences late when they test on other OSes. WebView2 uses Blink/Chromium while WKWebView and WebKitGTK both use WebKit, but even the two WebKit implementations diverge on GPU compositing, font rendering, and CSS filter support.

**How to avoid:**
- Test on all three platforms from Phase 1. Set up CI that screenshots key visual states on Windows, macOS, and Linux.
- Avoid CSS features with known cross-engine divergence: prefer `transform` + `opacity` for animations (universally GPU-accelerated) over `filter: blur()` and complex `box-shadow` stacks.
- For the signature glow-line effect, prototype on all three platforms before committing to an implementation approach. Consider using CSS `outline` or pseudo-elements with `box-shadow` rather than CSS `filter: drop-shadow()` which has inconsistent WebKit behavior.
- Build a visual regression test suite early (e.g., Playwright screenshots across platforms).

**Warning signs:**
- "It looks fine on my machine" during code review
- Visual bug reports that only reproduce on one OS
- Glow effects that appear blurry or missing on Linux

**Phase to address:**
Phase 1 (Foundation). The window chrome and glow-line perimeter must be validated cross-platform before any component work begins. If the core aesthetic breaks on a platform, everything built on top is wasted effort.

---

### Pitfall 2: Webview Hardware Acceleration Not Enabled by Default

**What goes wrong:**
CSS animations, canvas rendering, and filter effects run on CPU instead of GPU, causing janky 15-30fps performance instead of the required 60fps. This is especially severe on Linux (WebKitGTK historically had poor GPU compositing) and on Windows where WebView2 has a GPU blocklist that blocks hardware acceleration for many common GPU configurations.

**Why it happens:**
System webviews have conservative GPU blocklists to avoid crashes on problematic GPU drivers. Developers assume "webview = browser performance" but system webviews often ship with GPU acceleration disabled or limited. Tauri issue #4891 documented CSS filters consuming CPU instead of GPU on Windows, and WRY issue #617 showed CSS animations running at 14fps on Linux vs 100fps in Chromium.

**How to avoid:**
- On Windows, set `WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS="--ignore-gpu-blocklist"` before the Tauri builder initializes. This is a known workaround verified in Tauri's issue tracker.
- On Linux, ensure WebKitGTK is built with GPU acceleration support and test with the `WEBKIT_DISABLE_COMPOSITING_MODE` environment variable to verify compositing is active.
- Limit animation properties to only `transform` and `opacity` -- these are the only two properties guaranteed to be composited on a separate GPU layer across all engines. Animating `box-shadow`, `filter`, `background-color`, or `border-radius` triggers CPU repaints.
- Use `will-change: transform` or `transform: translateZ(0)` to promote elements to GPU composite layers, but do so sparingly (each layer consumes GPU memory).
- Build a performance benchmark into the demo app that reports actual FPS during animations.

**Warning signs:**
- Animations feel smooth in development browser but janky in the Tauri window
- CPU usage spikes during animations (visible in Task Manager/htop)
- Fan spinning up during what should be lightweight UI transitions
- Linux testers reporting significantly worse performance than Windows testers

**Phase to address:**
Phase 1 (Foundation). GPU acceleration configuration must be part of the framework's initialization code, not left to end users. The `HoloHue::init()` path should handle platform-specific GPU workarounds automatically.

---

### Pitfall 3: Tauri IPC Bridge Becomes Animation Bottleneck

**What goes wrong:**
Developers route animation state, timing, or per-frame data through Tauri's IPC bridge (invoke commands). Each IPC call has ~0.5ms overhead due to JSON serialization/deserialization. At 60fps, a frame budget is 16.6ms. If animation logic lives in Rust and sends per-frame updates to the webview via IPC, the serialization overhead alone can consume 3-5ms per frame (multiple state updates), leaving insufficient time for rendering.

**Why it happens:**
The natural instinct with Tauri is "Rust handles logic, webview handles display." For business logic, this split works well. For 60fps animations, the IPC bridge is too slow for per-frame communication. The Web Animations API / CSS animations run entirely within the webview's rendering pipeline and never cross the IPC boundary.

**How to avoid:**
- Animation choreography, timing, and execution must live entirely in the webview layer (JavaScript/CSS). Rust should not drive animations frame-by-frame.
- Rust's role should be: (a) configuration -- send animation presets/parameters once at setup, (b) triggering -- fire an event that says "play animation X on element Y", (c) completion -- receive a callback when animation finishes.
- Use Tauri's event system for fire-and-forget triggers rather than invoke commands for animation-related communication.
- Batch multiple state changes into single IPC calls when Rust does need to update the UI.
- For the ambient breathing/ripple effects, these should be pure CSS animations that loop indefinitely without any Rust involvement.

**Warning signs:**
- Animation code in Rust that calls `window.emit()` or `invoke()` inside a loop or timer
- Rust-side `requestAnimationFrame`-style timing logic
- Animations that stutter when other IPC calls are in flight

**Phase to address:**
Phase 2 (Animation System). The architecture decision of where animation logic lives must be made explicitly at the start of the animation phase. Document the boundary: "Rust triggers, JS/CSS executes."

---

### Pitfall 4: Tauri Multi-Window JavaScript Context Isolation

**What goes wrong:**
Unlike Electron, Tauri windows have completely isolated JavaScript contexts. You cannot share state, reactive stores, component instances, or SolidJS signals between the main window and subwindows. Each Tauri window is an independent webview with its own JS runtime. Developers design a subwindow system assuming they can pass references or share a store, then discover late that every subwindow must independently load the entire frontend bundle and synchronize state through IPC.

**Why it happens:**
Electron popularized the model of `window.open()` with shared context. Tauri's architecture fundamentally does not support this -- each webview is a separate OS-level web process. The Tauri documentation mentions this, but developers from Electron backgrounds miss it.

**How to avoid:**
- Design the subwindow system with isolated contexts from day one. Each subwindow loads the full HoloHue frontend.
- State synchronization between windows must go through Rust (the backend becomes the single source of truth). Use Tauri's state management API to hold shared application state in Rust, and push updates to all windows via events.
- Consider whether "subwindows" can actually be implemented as DOM-level overlays/panels within a single webview window rather than actual OS windows. For a dashboard framework, in-window panels that look like subwindows (with drag handles, close buttons, docking) avoid the multi-window problem entirely.
- If real OS windows are required (e.g., multi-monitor support), use a pub/sub event system through Rust: `window_a emits event -> Rust relays to window_b -> window_b updates`.
- Multi-monitor window placement has known bugs in Tauri (issue #14019) -- overlay windows may open on the wrong monitor.

**Warning signs:**
- Design documents that mention "shared state between windows" without specifying the synchronization mechanism
- Attempting to use `window.open()` or `window.opener` patterns
- Subwindow prototypes that work in development browser but fail in Tauri

**Phase to address:**
Phase 3 (Subwindow System). This is THE critical architectural decision for the subwindow phase. The in-window-panel vs real-OS-window decision must be made with full awareness of this limitation. Recommendation: default to in-window panels (DOM-based), with real OS windows as an optional advanced feature.

---

### Pitfall 5: crates.io 10MB Size Limit Blocks Distribution

**What goes wrong:**
HoloHue's value proposition is "cargo add holohue" -- but crates.io has a hard 10MB limit on published .crate files. A GUI framework with bundled audio files (ambient sounds, click SFX, hover sounds, transition sounds), font files, theme CSS, and possibly images/SVGs for UI elements will easily exceed 10MB. The crate fails to publish and the entire distribution model breaks.

**Why it happens:**
Developers build the framework with embedded assets using `include_bytes!` or `rust-embed`, which works locally but creates a binary that is too large for crates.io. Sound files (even compressed WAV/OGG) are several hundred KB each; a full soundscape with 20+ sound effects plus ambient tracks can easily be 5-15MB alone.

**How to avoid:**
- Do NOT embed audio files, fonts, or large assets in the crate binary. Use a separate asset distribution strategy:
  - Option A: A build script (`build.rs`) that downloads assets from a CDN/GitHub release on first build.
  - Option B: A companion `holohue-assets` crate (if assets fit in 10MB) or a git submodule.
  - Option C: Assets are generated/procedural (synthesized audio, CSS-only visuals, system fonts).
- For sounds specifically: consider generating UI sounds procedurally using the Web Audio API (oscillators, noise generators, envelope shapers) rather than shipping audio files. This eliminates the file size problem and gives users more customization.
- For the CSS/JS frontend bundle: use Tauri's standard asset embedding (which happens at the consumer's build time, not at crate publish time).
- Measure .crate size early: `cargo package --list` shows what will be published.

**Warning signs:**
- `cargo publish` fails with "crate too large" error
- The `target/package/` directory is suspiciously large
- Binary size growing faster than code changes would suggest

**Phase to address:**
Phase 1 (Foundation). The asset strategy must be decided before any assets are created. If audio files are chosen over procedural generation, the download/distribution mechanism must exist before the audio phase begins.

---

### Pitfall 6: Audio Autoplay Blocked by Webview Security Policies

**What goes wrong:**
The Web Audio API and HTML5 `<audio>` elements require a user interaction (click, keypress) before audio can play. Tauri inherits this browser security policy. HoloHue's "ambient background audio that starts when the app loads" and "UI sounds on hover" will be silently blocked. Ambient audio won't play on app start, and hover sounds may not work if the user hasn't clicked anything yet.

**Why it happens:**
This is a deliberate browser security feature to prevent annoying auto-playing audio. It affects all webview-based apps. Tauri issue #3478 specifically requests the ability to play audio without user interaction, and issue #9968 documents audio autoplay not working on Windows. On macOS (WKWebView/Safari), Web Audio is additionally buggy with pops, clicks, and wrong-speed playback.

**How to avoid:**
- Design the audio system to gracefully handle the "audio not yet unlocked" state. Show a subtle visual indicator, and unlock audio on the first user interaction.
- Use an AudioContext that is created and resumed on first user click/keypress. Once resumed, all subsequent sounds work (including hover sounds and ambient audio).
- Alternatively, use Rust-side audio (rodio/cpal) for ambient background sounds that need to play without interaction, and Web Audio for UI interaction sounds that naturally happen after user interaction.
- CRITICAL: If using Rust-side audio (rodio), be aware that rodio depends on ALSA (libasound2-dev) on Linux, which is a system dependency your users must have installed.
- Design the soundscape as opt-in rather than default-on: the first time the user enables sound, that click event unlocks the AudioContext.

**Warning signs:**
- Audio works in development browser but not in Tauri window
- Audio works on one platform but not another
- Console warnings about "AudioContext was not allowed to start"
- Ambient audio silently fails with no error

**Phase to address:**
Phase 4 (Audio System). But the architectural decision (Web Audio vs Rust-side audio vs hybrid) should be made in Phase 1 planning because it affects the dependency tree and platform requirements.

---

### Pitfall 7: Tauri Compile Time Tax on Framework Consumers

**What goes wrong:**
A Rust developer runs `cargo add holohue` then `cargo build` and waits 5-10+ minutes for initial compilation. Tauri alone pulls in ~300 crate dependencies. Combined with HoloHue's own dependencies (audio libraries, serialization, etc.), the first build becomes painfully slow. This destroys the "zero effort" developer experience that HoloHue promises. Developers evaluate frameworks partly on "how fast can I see something," and a 10-minute first build is a non-starter for many.

**Why it happens:**
Tauri's dependency tree is massive (webkit bindings, system libraries, IPC framework, crypto for isolation). Rust compilation is inherently slower than most languages. The `#[tauri::command]` proc macro is responsible for ~52% of compilation time in Tauri projects. Each additional dependency multiplies the problem.

**How to avoid:**
- Minimize the dependency tree. Use Cargo features aggressively so users only compile what they need: `holohue = { features = ["audio", "animations"] }` instead of pulling everything.
- Make the audio system an optional feature (it likely pulls rodio -> cpal -> platform audio bindings).
- Document expected build times honestly in the README.
- Provide a `holohue-lite` feature set that skips audio and heavy optional features for faster iteration.
- Configure the framework's build to use `[profile.dev] opt-level = 0` and suggest `rust-analyzer.cargo.targetDir` in dev setup docs.
- Consider whether the Rust backend needs all of Tauri's features or if a minimal Tauri feature set suffices.

**Warning signs:**
- `cargo tree | wc -l` shows 400+ dependencies
- Clean builds take more than 5 minutes
- Incremental builds take more than 30 seconds
- Users filing issues about "slow build" or "too many dependencies"

**Phase to address:**
Phase 1 (Foundation). The dependency budget must be set early. Every dependency added in later phases accumulates. Audit dependencies at each phase gate.

---

## Technical Debt Patterns

Shortcuts that seem reasonable but create long-term problems.

| Shortcut | Immediate Benefit | Long-term Cost | When Acceptable |
|----------|-------------------|----------------|-----------------|
| Hardcoding animation durations in CSS | Fast to implement | Every animation change requires CSS edits; users can't customize timing | Never -- use CSS custom properties from day 1 |
| Using `setTimeout` for animation sequencing | Simple choreography | Drift between timers, no cancellation support, breaks when tab is backgrounded | Never -- use Web Animations API or CSS animation-delay |
| Embedding assets with `include_bytes!` | Simple, single-binary output | Bloats crate beyond 10MB limit, increases compile time, wastes memory for unused assets | Only for tiny assets (<50KB total) like SVG icons |
| Inline styles instead of CSS classes | Quick prototyping | Impossible to theme, no cascade, specificity wars, no hover/focus states | Only in throwaway prototypes |
| Single global CSS file | No build tooling needed | Specificity conflicts, no scoping, grows unmanageable, collides with consumer CSS | Never for a framework -- use scoped/namespaced CSS |
| Skipping TypeScript types for IPC | Faster Rust-only development | Frontend/backend contract is implicit, breaks silently on changes | Never -- type-safe IPC from the start |
| Implementing subwindows as real OS windows first | Feels more "native" | Context isolation pain, state sync complexity, multi-monitor bugs | Only after in-window panels work fully |

## Integration Gotchas

Common mistakes when connecting components of the HoloHue system.

| Integration | Common Mistake | Correct Approach |
|-------------|----------------|------------------|
| Tauri IPC + SolidJS reactivity | Creating a SolidJS signal that triggers an IPC call on every change, causing IPC spam | Debounce state changes; batch updates; use Tauri events for one-way pushes |
| Web Audio + Tauri lifecycle | Creating AudioContext at app init (before user interaction) | Create AudioContext lazily on first user click; store reference for reuse |
| CSS animations + theme switching | Animations reference hardcoded colors, so theme changes don't affect in-flight animations | All animation colors must use CSS custom properties that resolve at paint time |
| Rust state + multiple webview windows | Assuming windows share JS state; using localStorage for cross-window communication | Rust `AppState` as single source of truth; emit events to all windows on state change |
| SolidJS + Tauri commands | Calling `invoke()` inside `createEffect()` without cleanup, causing leaked subscriptions | Use `onCleanup()` in effects; cancel pending invocations on component unmount |
| Frontend bundle + Tauri asset protocol | Serving frontend via `file://` protocol, breaking CORS and fetch() | Use Tauri's asset protocol (`tauri://` / `http://tauri.localhost`) which handles CORS correctly |
| CSS `clip-path` for angled corners + glow effects | Clipping the element also clips the box-shadow/glow that extends outside | Use a wrapper element: outer element has the glow, inner element has the clip-path |

## Performance Traps

Patterns that work at small scale but fail as component count grows.

| Trap | Symptoms | Prevention | When It Breaks |
|------|----------|------------|----------------|
| Too many GPU composite layers | Memory usage climbs; GPU texture memory exhausted; rendering becomes slower, not faster | Only promote animated elements to GPU layers; remove `will-change` after animation completes | >50 simultaneously promoted layers |
| Unbounded CSS `box-shadow` stacking for glow | Each shadow layer triggers a paint operation; stacking 4-5 shadows per element across 100 elements = 500 paint operations | Limit to 2-3 shadow layers per element; use pseudo-element opacity trick for animated glows | >30 glowing elements visible simultaneously |
| Per-component ambient animations | Every component has its own breathing/ripple CSS animation running continuously | Use a shared animation timeline; pause animations for off-screen elements using IntersectionObserver | >50 components with ambient animations |
| DOM event listeners for sound triggers | Each component adds its own mouseenter/click listener for sound effects | Use event delegation: single listener on a container element, dispatch sounds based on `data-` attributes | >100 interactive components |
| IPC polling for state sync | Frontend polls Rust backend every N ms for state changes | Use Tauri's event system: Rust pushes updates only when state actually changes | Any polling interval; always wasteful |
| Uncompressed audio assets loaded into memory | All sound effects loaded on app start, consuming 50-100MB of memory | Lazy-load sounds on first use; use compressed formats (Opus/OGG); implement an audio sprite sheet | >20 sound effects loaded simultaneously |
| SolidJS fine-grained reactivity triggering cascading re-renders | Theme change triggers every signal that depends on theme, causing hundreds of simultaneous DOM updates | Use SolidJS `batch()` for theme switches; structure signals so theme is a single root signal, not per-component | Theme changes with >200 reactive components |

## Security Mistakes

Domain-specific security issues for a desktop GUI framework.

| Mistake | Risk | Prevention |
|---------|------|------------|
| Overly permissive Tauri capabilities | Framework requests `fs:default`, `shell:default` etc. for convenience; consumers inherit unnecessary permissions | Request minimal capabilities; let consumers add permissions they need; never request shell or fs access by default |
| Loading external resources (CDN fonts/icons) | Breaks offline usage; CDN compromise = supply chain attack on all HoloHue apps | Bundle all fonts/icons; never load from external URLs; set strict CSP |
| User-provided theme values injected unsanitized | CSS injection via theme color values (e.g., `color: red; } body { display: none }`) | Validate theme values are valid CSS color tokens only; use a whitelist of CSS custom property names |
| Exposing internal IPC commands to consumer code | Consumer's frontend JS could call HoloHue's internal Tauri commands, bypassing framework API | Namespace all IPC commands; use Tauri's capability system to scope command access |
| `dangerousRemoteDomainIpcAccess` for convenience | Allows any remote page to call Tauri IPC commands | Never enable this; all content must be local |

## UX Pitfalls

Common user experience mistakes in cyberpunk/heavily-themed GUI frameworks.

| Pitfall | User Impact | Better Approach |
|---------|-------------|-----------------|
| Animations that cannot be disabled | Users with motion sensitivity (vestibular disorders) cannot use the app; violates WCAG | Respect `prefers-reduced-motion` media query; provide an API toggle; make all animations optional |
| Audio enabled by default | Startles users; unprofessional in office environments; accessibility issue | Audio off by default; clear toggle; remember preference |
| Low contrast cyberpunk text | Neon-on-dark looks cool but cyan-on-dark-blue can be unreadable at small sizes | Ensure minimum 4.5:1 contrast ratio for body text; test with color blindness simulators; offer high-contrast theme |
| Glow effects causing visual noise | Too many simultaneous glow animations create visual overload; important content competes with decoration | Glow effects should highlight, not saturate; limit simultaneous active glows; provide intensity settings |
| Window chrome that consumes too much space | Angled corners, thick glow borders, and decorative elements eat into content area | Keep chrome to 6-8px as specified; ensure content area is maximized; allow chrome to be minimized |
| Non-standard scrollbars | Custom-styled scrollbars lose platform-native behavior (right-click, middle-click, scroll speed) | Style scrollbars with CSS (`::-webkit-scrollbar`) but preserve native scroll behavior |
| Sound effects on every interaction | Hover sounds on 50 menu items = audio chaos when moving mouse across a list | Debounce hover sounds; limit concurrent sounds; no sound on rapid-fire interactions |

## "Looks Done But Isn't" Checklist

Things that appear complete but are missing critical pieces.

- [ ] **Window system:** Often missing keyboard-only window management (move, resize, close with keyboard) -- verify Tab/Enter/Escape work
- [ ] **Theme system:** Often missing runtime switching -- verify themes can change without page reload and in-flight animations adapt
- [ ] **Animation presets:** Often missing cancellation -- verify starting a new animation on an element cancels/completes the previous one cleanly
- [ ] **Sound system:** Often missing concurrent sound management -- verify playing 5 click sounds rapidly doesn't cause audio artifacts or memory leaks
- [ ] **Subwindow docking:** Often missing persistence -- verify docked positions survive app restart
- [ ] **Custom titlebar:** Often missing right-click context menu, double-click maximize, and drag-to-snap behavior on Windows
- [ ] **Cross-platform:** Often missing Linux testing -- verify on at least Ubuntu + one other distro; WebKitGTK rendering differs from WKWebView
- [ ] **Glow-line perimeter:** Often missing responsiveness -- verify the glow line adapts when window is resized, including at minimum sizes
- [ ] **Component focus states:** Often missing visible focus indicators -- verify every interactive component shows focus when tabbed to (critical for accessibility)
- [ ] **API ergonomics:** Often missing error messages -- verify Rust compiler errors from incorrect HoloHue API usage are helpful, not walls of generic trait bounds

## Recovery Strategies

When pitfalls occur despite prevention, how to recover.

| Pitfall | Recovery Cost | Recovery Steps |
|---------|---------------|----------------|
| Cross-platform rendering breaks | MEDIUM | Create per-platform CSS overrides using Tauri's platform detection; add platform-specific feature flags; worst case: use CSS that is conservative and works identically everywhere |
| GPU acceleration not working | LOW | Add the environment variable workaround to framework init; document platform-specific GPU flags; provide a software-rendering fallback mode |
| IPC bottleneck in animations | HIGH | Requires re-architecture: move animation logic from Rust to JS/CSS; refactor Rust animation controller to be a trigger-only interface; this is a fundamental design change |
| Context isolation blocking subwindows | HIGH | Requires re-architecture: either implement in-window panels (significant UI rewrite) or build a Rust-based state synchronization layer (significant backend rewrite) |
| Crate too large for crates.io | MEDIUM | Extract assets to companion crate or CDN; implement build.rs asset downloader; refactor `include_bytes!` to runtime loading; most code stays the same |
| Audio autoplay blocked | LOW | Implement lazy AudioContext initialization; add "click to enable audio" UX flow; this is a contained change in the audio subsystem |
| Compile time too slow | MEDIUM | Audit and remove unnecessary dependencies; add Cargo features for optional subsystems; document workspace configuration; hard to fix once dependency tree is established |

## Pitfall-to-Phase Mapping

How roadmap phases should address these pitfalls.

| Pitfall | Prevention Phase | Verification |
|---------|------------------|--------------|
| Cross-platform rendering inconsistencies | Phase 1 (Foundation) | Screenshot comparison tests across Windows/macOS/Linux for core window chrome |
| GPU acceleration disabled | Phase 1 (Foundation) | FPS counter in demo app shows 60fps during test animations on all platforms |
| IPC animation bottleneck | Phase 2 (Animation System) | Architecture doc explicitly states "animations execute in webview only"; no Rust-side frame loops |
| Multi-window context isolation | Phase 3 (Subwindow System) | Subwindow prototype demonstrates state sync through Rust; no shared JS references |
| crates.io size limit | Phase 1 (Foundation) | `cargo package` produces .crate file under 10MB; asset strategy documented |
| Audio autoplay blocking | Phase 4 (Audio System) | Audio plays correctly on cold start (after first click) on all three platforms |
| Compile time tax | Phase 1 (Foundation), ongoing | Clean build time measured at each phase gate; dependency count tracked |
| Excessive glow/shadow performance | Phase 2 (Animation System) | Benchmark with 50+ glowing components maintains 60fps |
| Theme values CSS injection | Phase 2 (Theme System) | Theme validation rejects non-color values; test with adversarial inputs |
| Motion sensitivity / accessibility | Phase 2 (Animation System) | `prefers-reduced-motion` disables all animations; all components keyboard-accessible |
| Audio on every interaction | Phase 4 (Audio System) | Hover sound debounced; rapid clicks produce clean audio without artifacts |
| Subwindow position persistence | Phase 3 (Subwindow System) | Layout survives app restart; positions stored via Tauri store plugin |

## Sources

- [Tauri Architecture](https://v2.tauri.app/concept/architecture/) -- HIGH confidence, official documentation
- [Tauri Window Customization](https://v2.tauri.app/learn/window-customization/) -- HIGH confidence, official documentation
- [Tauri Multi-Window Discussion #9423](https://github.com/tauri-apps/tauri/discussions/9423) -- MEDIUM confidence, community discussion
- [Tauri Multi-Window Context Isolation Discussion #11643](https://github.com/tauri-apps/tauri/discussions/11643) -- MEDIUM confidence, community discussion
- [Tauri Issue #4891: No hardware acceleration for canvas and CSS](https://github.com/tauri-apps/tauri/issues/4891) -- HIGH confidence, resolved issue with verified fix
- [WRY Issue #617: Slow CSS animation performance on Linux](https://github.com/tauri-apps/wry/issues/617) -- HIGH confidence, resolved issue
- [Tauri Issue #6577: CSS performance on macOS is bad](https://github.com/tauri-apps/tauri/issues/6577) -- MEDIUM confidence, platform-specific issue
- [Tauri Issue #3478: Play audio without user interaction](https://github.com/tauri-apps/tauri/issues/3478) -- HIGH confidence, confirmed limitation
- [Tauri Issue #9968: Audio autoplay not working on Windows](https://github.com/tauri-apps/tauri/issues/9968) -- HIGH confidence, confirmed bug
- [Tauri Issue #14019: Multi-window multi-monitor bug](https://github.com/tauri-apps/tauri/issues/14019) -- MEDIUM confidence, open issue
- [Tauri Issue #3571: Inflated build time due to heavy dependencies](https://github.com/tauri-apps/tauri/issues/3571) -- HIGH confidence, confirmed limitation
- [Tauri IPC Improvements Discussion #5690](https://github.com/tauri-apps/tauri/discussions/5690) -- MEDIUM confidence, architecture discussion
- [crates.io Publishing Guide](https://doc.rust-lang.org/cargo/reference/publishing.html) -- HIGH confidence, official Rust documentation
- [crates.io Size Limit Issue #195](https://github.com/rust-lang/crates.io/issues/195) -- HIGH confidence, confirmed 10MB limit
- [Rust Issue #65818: include_bytes! slow compilation](https://github.com/rust-lang/rust/issues/65818) -- MEDIUM confidence, known compiler issue
- [Cross-Platform Layout Differences in Tauri Discussion #12311](https://github.com/tauri-apps/tauri/discussions/12311) -- MEDIUM confidence, community discussion
- [A 2025 Survey of Rust GUI Libraries](https://www.boringcactus.com/2025/04/13/2025-survey-of-rust-gui-libraries.html) -- MEDIUM confidence, comprehensive community survey
- [Smashing Magazine: Orchestrating Complexity with Web Animations API](https://www.smashingmagazine.com/2021/09/orchestrating-complexity-web-animations-api/) -- MEDIUM confidence, established web resource
- [Smashing Magazine: CSS GPU Animation Doing It Right](https://www.smashingmagazine.com/2016/12/gpu-animation-doing-it-right/) -- MEDIUM confidence, established web resource (older but principles hold)
- [MDN: Animation Performance and Frame Rate](https://developer.mozilla.org/en-US/docs/Web/Performance/Guides/Animation_performance_and_frame_rate) -- HIGH confidence, authoritative documentation
- [rodio GitHub](https://github.com/RustAudio/rodio) -- HIGH confidence, official repository
- [cpal GitHub](https://github.com/RustAudio/cpal) -- HIGH confidence, official repository

---
*Pitfalls research for: Hybrid Rust+webview cyberpunk GUI framework (HoloHue)*
*Researched: 2026-02-25*
