Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ by installed OpenStudio apps. Start with [README.md](README.md) and
The image GraphQL service has been retired.
- Keep decorative controls out of keyboard navigation and preserve reduced-motion
alternatives, menu focus behavior and readable content before JavaScript.
Small viewport size must not disable illustration playback. Verify that phones
actually animate on first visit, while offscreen and hidden-tab timelines pause.

## Content and branding

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ Run `npm run build` before `npm test` in a clean checkout; tests consume the gen
- Browser tests cover all canonical routes at 390, 768 and 1440 px, legacy redirects/404s, navigation and keyboard behavior, privacy consent, lazy-load recovery and GitHub release label/link consistency.
- SEO browser tests visit every sitemap page with JavaScript disabled and enabled, compare the head metadata and structured data, validate social-image dimensions, and check metadata cleanup during navigation and 404 recovery.
- Focused browser regressions cover normal-motion two-piece loading, AI card/table layout, current-page mobile-menu activation, and Features/NAM image selection at standard and high-density resolutions. Build tests check upgrade guidance before JavaScript; contract tests reject malformed repository snapshots and verify retry behavior.
- Illustration tests delay or fail the animation-engine request, verify that the same scene elements and dimensions remain, and cover prerendered artwork with JavaScript disabled. Ordinary screenshot/thumbnail delivery tests remain separate.
- Illustration tests delay or fail the animation-engine request, verify that the same scene elements and dimensions remain, and cover prerendered artwork with JavaScript disabled. Phone tests check real playback on fresh visits, delayed loads and uncached navigation, plus offscreen pausing, reduced motion and every NAM tile. Ordinary screenshot/thumbnail delivery tests remain separate.
- The suite also includes unit, source-contract and build tests. A reported total is not an E2E-only count. Desktop app tests live in the separate app repository.
- Browsers currently run in Chromium. The eight-width visual comparison recorded in the audit is a manual review artifact, not an automated screenshot-regression suite. Firefox/WebKit coverage and CI screenshot baselines are follow-up improvements.
- Loading performance is an explicit `npm run verify:perf` check; the current CI workflow does not run that matrix automatically.
Expand Down
8 changes: 5 additions & 3 deletions blogs/2026-09-16-minimax-stable-audio-diffusers-openstudio.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,13 @@ Downloads reuse completed cached files when you retry. A failed or cancelled set

## What about a smaller, quantized MiniMax?

**This release does not offer a supported quantized MiniMax download or a general-purpose INT8, INT4 or GGUF option.** There is experimental INT8 work in the app repository, including checks for a locally qualified configuration. That is not a low-VRAM model we can tell everyone to install.
**Update, 16 September 2026:** development builds containing [app commit `681fec8`](https://github.com/sdevil7th/OpenStudio/commit/681fec8) now offer **Original** and **INT8** model versions for all three models. In **AI Tools Setup**, **Download and Prepare INT8** reuses installed original weights or downloads the official originals, then saves and verifies a separate quantized copy. This is a local preparation step, so the first download is not smaller. Prepared OpenStudio INT8 folders can also be imported. Older installed releases may not have these controls.

The available memory-saving approach is **offloading**. OpenStudio can keep components on the GPU when there is room, or move components and language-model layers between system RAM and the GPU. This reduces how much must fit in VRAM at once. Transfers take time, and the model still needs substantial system RAM.
INT8 currently requires an **NVIDIA CUDA GPU**. It reduces the precision of MiniMax's language-model weights, or the diffusion-transformer weights in ACE-Step and Stable Audio; the other audio components keep their normal inference precision. The model picker remembers the selected version on the AI track, and Original and INT8 have separate installation status. There is no general-purpose INT4 or GGUF selector.

Quantization would change how the weights are represented to make them smaller. Offloading changes where they live. A machine with less VRAM can benefit from offloading and still run out of system memory, especially with a long song request.
This makes MiniMax more practical on the configuration we checked, but it does not turn it into a tiny model. The app's [qualification report](https://github.com/sdevil7th/OpenStudio/blob/681fec8/docs/ai-quantization-2026-09-16.md) records real generation with an RTX 4080, 16 GB VRAM and 32 GB system RAM. Long songs can still take many minutes, and MiniMax INT8 uses about 15 GiB of temporary disk cache for inactive stages. Those checks do not establish support for every smaller GPU or prove that quantized output sounds identical.

Quantization makes weights smaller; **offloading** controls where components live while they are needed. Moving data between storage, system RAM and the GPU takes time. Lower memory use is useful, but it does not guarantee faster generation. Other GPU backends and CPU-only systems should use Original, where the model's hardware checks allow it. The [model-version setup guide](/docs/ai-runtime-setup#model-versions) covers the controls and installation details.

Use the app's **Hardware check** for the request you intend to run, and refresh it after closing other applications. It is an estimate, not a guarantee that every stage will fit. We are not claiming universal support for a particular small GPU. Hugging Face's [memory optimization guide](https://huggingface.co/docs/diffusers/optimization/memory) is a useful explanation of the underlying tradeoffs.

Expand Down
103 changes: 101 additions & 2 deletions docs/illustration-loading.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ their bandwidth without fixing the scene change.
screenshot, bitmap crossfade or second scene to replace it.
- `useStageTimeline` loads GSAP after initial loading, only when the visible
stage has a playback slot. It animates the same DOM elements. Off-screen,
hidden-tab and scheduler-limited timelines pause; reduced-motion and small
stages retain their authored static state.
hidden-tab and scheduler-limited timelines pause; reduced motion and explicit
playback disabling retain their authored static state. Visible illustrations
animate at phone, tablet and desktop sizes.
- `LiveStage` reserves its aspect ratio and uses `content-visibility: auto` so
the browser can skip layout and painting of distant off-screen scenes. This
does not substitute another scene or remove the actual renderer's DOM. It is
Expand All @@ -56,6 +57,104 @@ their bandwidth without fixing the scene change.
barrel. Text/legal pages still exclude NAM/DAW/GSAP code. Standalone screenshots
in articles, guides and nonanimated cards continue to use responsive images.

## Initial-load lifecycle correction — 16 September 2026

The initial HTML loader (`#openstudio-instant-loader`) emits
`openstudio:intro-hidden` once and records completion in
`window.__openstudioIntroHidden`. Later route loaders reuse its artwork and
`data-openstudio-loader` attribute, but have their own entrance/exit lifecycle.
They do not emit the initial-intro event.

The startup scheduler previously waited for that event whenever *any* loader was
present. If the initial loader timed out before the first route's code arrived,
or a visitor navigated to an uncached route, the illustration could mount while
a route loader was still exiting. The initial event had already happened, so the
GSAP request was never scheduled. Waiting longer did not help; a reload could
avoid the timing window.

`scheduleAfterInitialLoad` now checks the recorded completion state and the
specific initial loader. An exiting route loader cannot restart the initial
wait. The existing idle delay, input scheduling and cancellation remain intact;
GSAP still loads only for eligible visible illustrations. No loader artwork,
layout, animation sequence or screenshot fallback changes are part of this fix.

`test/initial-load.test.mjs` covers both readiness orders, absent initial loaders,
idle/input scheduling and cancellation. `test/first-load-animation-browser.test.mjs`
holds the production Home chunk past the real initial-loader timeout and tests
uncached navigation at 768 and 1440 px. It verifies that the scene's clock advances
without a refresh or further interaction; a `playing` attribute alone would also
pass for the intentionally static reduced-motion frame. Reduced motion is checked
separately for a stable clock and no animation-engine download. The slow-entry
and normal-motion navigation regressions failed against the pre-fix build.

After this fix, the production build (including strict TypeScript), zero-warning
lint and all **147 tests** pass. The unchanged core performance matrix passes
**10 of 10 cases**; it does not include the separate NAM Rack network limitation
recorded below. Generated CSS hashes match the pre-fix build. Local reproduction
and check logs are retained in ignored `output/review/first-load-*` files and
`output/review/production-reproduction.log`.

## Phone playback correction — 16 September 2026

The initial-load event fix above did not address a separate size gate. Every
illustration disabled its timeline below 60% of its design width (45% for the
compact NAM chain). Home scales to approximately 41%, 52% and 58% at 320, 390 and
430 px, respectively. These phones therefore never requested GSAP, even with
normal motion enabled. Waiting or refreshing could not remove the size gate.

Removed that gate from Home and all eight stage renderers. Viewport size now
controls only layout. The shared driver still honors reduced motion, explicit
disabling, document visibility and its two-active-stage limit. Small NAM tiles
can share a viewport; the most eligible two play, and scrolling changes their
eligibility. Other tiles hold their frame instead of all consuming animation
work simultaneously.

The all-tile test also exposed fractional clipping in the NAM grid: amp/cab
reported a 0.99865 intersection ratio while the following EQ/post row reported
1. The latter kept taking both slots even after scrolling amp/cab into view.
The scheduler now treats at least 99% visibility as fully visible, retaining
the priority order and two-stage cap. A regression using the measured fractions
fails against the previous scheduler and passes with this correction.

Reload stress checks found another intermittent stall: the driver was settled,
the document visible and the intro complete, but every stage still had a zero
intersection ratio. Visibility observation now starts after the initial-loading
gate, and returning to a visible tab requests a fresh observation. This avoids
depending on measurements made while the route was hidden. Browser coverage
simulates missed loading-time visibility notifications and verifies that reload
still starts the clock without a scroll, tap or another refresh.

The original artwork, sizing, loop choreography and two-piece loader are intact.
Phones now use the existing animation rest frame and start playback instead of
remaining on the reduced-motion sample. No screenshot placeholders were added.
All four generated CSS bundle hashes match the preceding build.

The earlier rest-frame test only required Home playback at widths of at least
768 px. It now includes 390 px. First-load coverage adds delayed phone entry,
uncached phone navigation and reduced-motion phone navigation; the two
normal-motion regressions failed before the size-gate removal. The dedicated
mobile browser test checks fresh 320/390/430 px contexts with touch/mobile
emulation, actual clock advancement without input, offscreen pause/resume,
all eight illustration types and the rack tour plus all six smaller rack tiles.
Tile checks scroll the relevant row below the sticky header so it can receive
a playback slot. Canvas repainting alone is not treated as proof of a running
scene timeline.

This is Chromium phone emulation, not physical Android/iOS or Safari testing.
Local evidence is under ignored `output/review/mobile-animation-fix/` and
`output/playwright/phone-*` files. The AI guide's accompanying INT8 correction
is sourced separately in [the music-model review](music-models-blog-review.md).

The final production build (including strict TypeScript), zero-warning lint and
all **181 tests** pass. Earlier failed runs are retained: they exposed the phone
cutoff, fractional NAM visibility and intermittent zero-intersection reload.
The controlled visibility regression fails before the observer lifecycle change
and passes afterward; the final full suite includes that scenario.
The unchanged core performance matrix passes **10/10** cases. A separate mobile
NAM Rack check measures 3.12 s reveal-adjusted LCP, zero layout shift, 376 ms of
long tasks and 664.6 KiB encoded. Its 48 requests still exceed the generic limit
of 35; no request budget was raised. These are local throttled measurements.

## Performance tradeoff

A still image can give a cheap early paint while complex rendering code loads;
Expand Down
10 changes: 10 additions & 0 deletions docs/music-models-blog-review.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@ authors. It makes no new speed benchmark or subjective audio-quality claim.

## Source checks

**INT8 follow-up — 16 September 2026:** the quantization paragraph below records
the original review against `7f59cff`. App commit `681fec8` subsequently added
explicit Original/INT8 selection and separate prepared installations for all three
generation models. The article and AI runtime guide now reflect that development
behavior. Verified the selector, setup modal, AI-track persistence tests,
`ai_model_variants.py`, `prepare_diffusers_audio.py`, generation preflight and the
committed quantization report. The copy retains NVIDIA CUDA restrictions, original
download size, MiniMax's disk-cache cost and the limits of the RTX 4080 evidence.
This website review did not rerun native GPU generation or qualify other hardware.

Desktop base: `7f59cff92c4a5f70704ba5985e7da373900d6162`. The AI source files
listed below were committed in that checkout. Its user manual and automation
implementation also have concurrent working-tree edits; those were not treated
Expand Down
24 changes: 24 additions & 0 deletions docs/visual-regression-correction.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,29 @@
# Visual regression correction — 16 September 2026

## Follow-up: mobile download requirements

The download page's 640 px minimum-width comparison grid gave the sticky label
column about 227 px, even inside a 280–350 px phone card. That left very little
room for the values and covered text as the visitor scrolled sideways.

Below 640 px, the requirements now use a definition list: each component has
full-width Minimum and Recommended values. All four components and eight values
come from the same `systemRequirementMatrix` as the larger-screen comparison.
CSS selects the layout, so it also works before JavaScript and when the viewport
changes. There is no extra request or screen-size JavaScript. The phone section
is intentionally taller because every value is readable without horizontal
scrolling. The side-by-side comparison remains at 640 px and wider.

Visual captures cover 320, 390, 640, 768, 900, 901 and 1440 px. The comparison
grid's columns and styling match the approved `97a3f2e` design; the retained
current copy is unchanged. Before/after captures at 768, 901 and 1440 px are
pixel-identical; 640 and 900 px retain the same dimensions with six and one
different pixels respectively. Phone captures were inspected for text wrapping
and spacing. Evidence is in ignored `output/playwright/requirements-*.png`.
`test/redesign-routes-browser.test.mjs` checks all eight values for clipping at
phone widths, the layout switch at 640 px, both sides of the navigation breakpoint,
and the JavaScript-disabled phone page.

## What happened

The branding/cleanup work replaced suprabho's two-piece SVG loader with a single
Expand Down

Large diffs are not rendered by default.

Loading