The biggest release since launch. NSS is now a full image + video editor, not just a background remover. New `/all-in-one` landing tells the broader story; the existing `/` bg-remover landing is unchanged for SEO continuity.
New landing page
`/all-in-one`
Comprehensive landing surfacing every editor and tool with prominent CTAs.
Header link added (`All-in-one` between `All Tools` and `Blog`).
Sitemap entry at priority 0.9 with weekly change frequency.
The original `/` page remains the BG remover landing — users searching "background remover" still land there directly with no SEO impact.
Shared layer architecture
Image editor, video editor, and staging tool all use the same `<LayersPanel>`
Shared types in `src/types/layers.ts`: image layers (`image` / `cutout` / `brush` / `filter` / `adjust` / `bg-fill` / `text` / `shape` / `relief3d`), video layers (`video` / `image` / `text` / `filter` / `effect`), staging layers (`room` / `furniture`).
Each layer has visibility, lock, opacity (0–1), and blend mode (12 modes: normal, multiply, screen, overlay, soft-light, hard-light, darken, lighten, color-burn, color-dodge, difference, exclusion).
Multi-file drag-and-drop creates one layer per file — image files become image layers, video files (in video editor) become video-source layers.
Drag-and-drop reordering with row-level drag handles; thumbnail previews per layer kind.
Layer-aware canvas rendering: `Canvas.tsx` walks `editorStore.layers` after the base mask render and composites image / text / shape / bg-fill kinds with their opacity + blend mode applied via `globalCompositeOperation`.
Layer-aware video preview: per-frame composite in `VideoPreviewCanvas.tsx` walks `videoEditorStore.layers` and renders image / text overlays at their start/end times.
INT1 — Drag-to-position for image and text overlay layers on the image canvas. Hit-test cached `layerBoundsRef`; drag updates `layer.x / y` in the store. Brush / wand fall through if no layer is under the pointer.
L5 — Layer persistence in `.nss-project` files. `project.json` carries layer metadata; bitmaps and masks go into separate ZIP entries (`layers/layer-<id>-bitmap.png`, `layers/layer-<id>-mask.bin`). Original layer ids preserved on import so future ops keep referencing them.
L6 — Layer undo / redo via `historyStore` extension. `HistoryEntry` gained `kind: 'mask' | 'layers'` and `layersSnapshot`; the `layerHistory.ts` subscriber pushes snapshots on every layer mutation, `Canvas.tsx` Ctrl+Z routes layer-kind entries through `applyLayerSnapshot()`. Merge-active-layer-down action shipped.
L7 — Layer keyboard shortcuts: `Ctrl+J` duplicate, `Ctrl+Shift+]/[` to-front / to-back, `Delete` remove active layer. Registry entries in `src/lib/editor/keyboardRegistry.ts`.
INT4 — Video `textOverlays` legacy array now mirrors into `layers[]` on every add / update / remove so a single composite path renders both. Legacy VideoTextOverlay panel still works; layers stack is the unified source-of-truth.
INT5 — AI commands for layer management: `add text layer "..."`, `list layers`, `delete layer`, `select layer X`, `hide layer`, `show layer`, `bring to front`, `send to back`, `move up`, `move down`, `duplicate layer`, `set layer opacity to N%`. All wired in `imageTools.ts` + `fallback.ts`.
3D mode
`three` (MIT) installed and dynamic-imported
`Scene3D` shipped in `src/components/staging/Scene3D.tsx` — room photo as a textured floor plane, furniture as billboard sprites, OrbitControls camera, click-to-select with `TransformControls` translate gizmo.
3D1 — Click-to-select via raycaster + gizmo attach. OrbitControls pauses while the gizmo is being dragged so the camera doesn't fight user input.
3D2 — Stock furniture palette: 7 SVG cutouts (sofa, armchair, coffee-table, floor-lamp, plant, rug, bed) in `public/staging/furniture/`. `<FurniturePalette>` UI renders the grid; one-click adds to the scene through the same `addFurnitureFiles` path as drag-drop.
3D3 — Visual polish: radial-gradient soft contact shadow under each sprite (replaces flat ellipse), centre-sampled room-colour tint applied at ~12 % to each sprite material so items don't look pasted-in.
3D4 — `Relief3D` component generates depth-displaced bas-relief meshes. Reuses the existing `depth.worker.ts` (originally for portrait blur) via `getDepthMap.ts` → samples per-vertex Z displacement on a 128×128 plane geometry → user gets real parallax when orbiting. No new ML model.
3D5 — Image editor 3D: lighting intensity (0–2) + angle (0–360°), material preset (Matte / Glossy / Metallic — maps to roughness/metalness), background environment colour picker. Live-applied via Scene3D props.
3D6 / 3D8 — 4-second 360° orbit recorder. `MediaRecorder` on the renderer's canvas → WebM download. Works for image preview, staging, and video editor 3D modes.
3D7 — Video editor 3D: data-attribute on the preview canvas + window event listener mounts `Scene3D` with the current frame snapshotted as `roomBitmap`. Captured live from the existing video preview pipeline — no new render path needed.
3D9 — `overlayPlanes` prop accepts additional PIP planes (image-on-image, video-on-image) for picture-in-picture 3D compositions.
J4 — Image editor `Preview3DPanel` exposes both "flat plane" and "3D relief" modes through a full-screen modal with the new lighting / material / background controls.
Agentic AI
`goalRecipes.ts` — high-level intent expansion
High-level prompts ("make this professional for an e-commerce listing", "moody portrait", "vintage look", "TikTok prep", "talking-head clean-up") match a recipe pattern and expand into concrete multi-step plans.
AI announces the plan with numbered steps, then runs each through the existing `parseMultiStepCommand` / `executeToolCall` pipeline.
9 recipes shipped (7 image + 2 video). Adding more is one entry per recipe in `GOAL_RECIPES`.
`toolGuidance.ts` — comprehensive per-tool KB
30+ tool guides covering every tool, utility, and command in the app. Each entry has keywords, a usage body, and copy/paste-able example commands.
AI panel falls through to this when the regex parser + bridge + filter-suggestion all fail. Returns the top 3 guides by keyword score, or a curated category summary if nothing matches.
15 new "how do I X" KB entries in `fallback.ts` covering layers, 3D, tuning, collab, lifestyle scenes, palette extraction, transparency check, compression — every one tells users the exact command(s) to use.
`commandBridge.ts` — registry executor fallback
After the existing `@/lib/ai/fallback.ts` lexical parser fails, the bridge tries `@/lib/commands/commandParser.ts` + `commandExecutor.ts` against the registry of 30+ commands. Processing modules (`@/lib/processing/*`) are dynamic-imported on use.
Resolves the previous gap where the registry existed but wasn't wired to AiPanel — now every registry command is callable from the AI panel.
Floating quick-actions toolbar
`CanvasQuickActions` (image editor) and `VideoCanvasQuickActions` (video editor)
Photoshop-style floating toolbar above the canvas with icons for: undo / redo / zoom in-out / fit / AI panel / keyboard shortcuts.
Drag handle on the left — drag to reposition; position persists in `localStorage` (`nss-canvas-quickbar-pos` and `nss-video-quickbar-pos`).
Dropdown popovers: filter grid (22 presets, click to apply), background (transparent / solid / gradient + 16 lifestyle scenes), adjustments (inline sliders), export (quick PNG / WebP / AVIF / JPG).
Video-editor variant: play / pause, playback rate, colour grading sliders, 3D preview, export, AI panel.
Mobile: auto-collapses, expand via `⋯` button.
R-TUNE inference application
Active tuning profile now flows into the inference worker
`useQueueProcessor.ts` reads `nss-active-tuning-profile` from localStorage, loads from IndexedDB via `tuningProfile.ts`, converts to `TuningOverrides` via `activeTuning.ts`, passes to the worker.
`inference.worker.ts` request shape gained `tuning?: WorkerTuning` (fringe deltaE, force erosion, guided strength, erosion radius, profile label).
`fringeDecontaminate.ts` honours `options.deltaE` (scales the raw threshold linearly) and `options.forceErosion`.
Same overrides applied through the `removeBackground.ts` processing module so AI-panel-initiated BG removal also picks up the user's active profile.
R-SAM click-to-select
New editor tool: `select-subject` (S hotkey, 🎯 icon)
Tool sidebar + properties panel + mobile bar all updated.
Click anywhere on the canvas → `Canvas.tsx` `onSelectSubjectClick` calls the existing `selectSubject()` flood-fill in `src/lib/sam/selectSubject.ts` (CPU Lab ΔE flood-fill with edge cleanup).
Selection tolerance reuses the Magic Wand slider; result writes through the same mask path as Magic Wand, so undo/redo work identically.
R-COLL collaborative sessions
`CollabPanel` in the editor's Properties panel
Start a session (auto-generated ID) or paste an existing ID to join.
Status pill: idle / connecting / connected / disconnected / error.
Activity log shows incoming operations and connection events.
Copy-ID button + manual ID display.
WebRTC signalling endpoint at `/api/collab-signal` is the only server hop — pixel data and operations all stream peer-to-peer.
GIF queue serialization
`useGifProcessor.ts` rewrite (part of E3+X1)
Added `processingRef` guard + auto-driver effect that picks the next `queued` job after the active one ends.
`GifDropZone.tsx` simplified to enqueue-only; no more parallel worker spawn on multi-file drop.
Cancel resets the guard so subsequent jobs start without page refresh.
Pattern proven for remaining 7 video utilities (still pending; one tool per future session).
Help centre + SEO
Help articles
13 new help articles written + 9 previously orphan articles registered. Now 59 total articles in `helpContent.ts`.
New articles cover every utility tool and the new feature surface: image-resizer, image-compressor, format-converter, png-optimizer, color-extractor, compare-formats, check-transparency, metadata-remover, rotate-flip, grayscale, color-picker, add-background, video-format-converter, video-compressor, video-resizer, video-rotate, video-canvas-extender, video-format-comparison, real-estate-staging.
`ai-image-editing.mdx` fully rewritten to cover layers, 3D, tuning, collab, goal recipes, and the new "how do I X" guidance flow.
Sitemap
`/all-in-one` added at priority 0.9.
7 missing tool routes added (real-estate-staging + 6 video utilities).
`/editor`, `/video-editor`, `/lifestyle-composer` added as top-level entries (priority 0.9 / 0.9 / 0.8) for SEO discoverability.
R-LANG depth
25+ new translated UI keys added to `en` + `es` + `de` + `pt` + `ja` covering the new editor / layers / AI sections. Runtime fallback to English preserved for any string not yet translated.
Other shipped (foundation level — see prior changelogs for details)
R-PROJ project export / import with full layer round-trip.
R-BVID batch video processing ZIP download.
R-PWA full PWA + offline + SW pre-warm.
INT3 V1: `bg-fill` layer kind renders as full-canvas colour / gradient / pattern overlay.
INT6: Select-Subject tool present in mobile editor bar.
R-LLM — opt-in local AI assistant
`@mlc-ai/web-llm` v0.2.84 installed. Package is dynamic-imported only when the user opts in, so default editor startup is unaffected (zero bytes of LLM code in the initial bundle).
3 quality tiers in `LLMOptInPanel`: **Fast** (Qwen 0.5B, ~500 MB, 2 GB VRAM), **Balanced** (Llama 1B, ~800 MB, 3 GB VRAM), **Smart** (Phi-3 mini, ~2.2 GB, 4 GB VRAM). User picks at opt-in time.
Model weights cached in IndexedDB via web-llm's built-in loader — download is one-time per browser.
`AiPanel` tries LLM resolution FIRST when ready; falls through to existing rule-based parser → command bridge → goal recipes → guidance KB on any failure. Zero UX regression when LLM unavailable, still downloading, or returns malformed JSON.
New PropertiesPanel accordion: `🤖 AI assistant model`.
A1 — PWA icon unified (was reported as not displaying on installed app)
Existing `public/icons/*.png` files already contained the purple-sparkle brand mark; the issue was wiring + cache inconsistency between `src/app/icon.svg` (was black "N" tile) and the PWA install icon (purple sparkle).
`src/app/icon.svg` rewritten to match the purple-sparkle so browser tab favicon, "Open in app" chip, and PWA install icon all show the same brand mark.
`src/app/icon.png` (512×512) and `src/app/apple-icon.png` (192×192) added — Next.js App Router conventions iOS reads first for "Add to Home Screen".
`manifest.ts` icon URLs now carry `?v=4` query — bumping `ICON_VERSION` on each brand-mark change forces the OS install pipeline to re-fetch (browsers cache PWA icons by URL).
Service worker cache bumped `v3 → v4` to invalidate any stale icon entries from prior installs.
SW `fetch` handler serves all icon paths (`/icon.{svg,png}`, `/apple-icon.png`, `/favicon.ico`, `/icons/*`) network-first — future logo changes propagate within one page load instead of waiting for the SW lifecycle.
After deploy: users with old PWA installs uninstall + reinstall once to pick up the new icon; new installs and browser-tab favicons show the sparkle immediately.
ML model audit — no swaps, all top-tier confirmed
| Tool | Model | Status |
|------|-------|--------|
| Image BG Fast | `briaai/RMBG-1.4` | Industry standard. RMBG-2.0 has restrictive licence — keep 1.4. |
| Image BG Best | `onnx-community/BiRefNet-ONNX` | Highest quality client-side. |
| Depth (portrait blur + 3D relief) | `Xenova/depth-anything-small-hf` | Latest small variant. |
| Image upscaler | `Xenova/swin2SR-classical-sr-x2-64` | Best client-side x2 SR. |
| LLM (R-LLM) | Qwen 0.5B / Llama 1B / Phi-3 mini | 3-tier opt-in. |
| `@huggingface/transformers` | v3.8.1 | Current major. |
| `@mlc-ai/web-llm` | v0.2.84 | Current. |
R-VO — Video object removal (V1)
`VideoObjectRemover` panel shipped in the video editor's effects sidebar — covers the most common ask ("remove the watermark / channel logo / timer overlay from this clip").
Pick a corner preset (top-left / top-right / bottom-left / bottom-right), dial the region size (5–40 % of frame) + temporal window (±3–30 frames), hit Process.
Pipeline: decodes frames at 15 fps via `<video>` + canvas, builds a rectangular mask, runs the existing `removeObjectFromFrames` temporal median fill, re-encodes via MediaRecorder (VP9 / VP8 / WebM fallback).
Output previews inline with a download link.
V2 — interactive brush UI for arbitrary-shape regions — is a dedicated session.
E3+X1 — utility queue migration
GIF migrated with the full pattern (Zustand store + processingRef guard + auto-driver effect, simplified DropZone).
7 video utility tools (compressor, format-converter, resizer, rotate, canvas-extender, metadata-remover, format-comparison) are single-file by design — each takes one video, runs one transform, produces one output. Their existing single-file UX is appropriate; queue migration would only add value if users start asking for multi-video batches. Deferred unless user-requested.
R-PHOTO — Real photography template wiring (final)
`LifestyleComposerZone` thumbnail loader now prefers `photoUrl` over `svgUrl` per template via a HEAD request — when a photo exists at the expected path it renders, otherwise falls back to the SVG mockup. No code change needed to roll in photos one at a time.
All 14 lifestyle templates have their `photoUrl` field populated with the canonical path `/templates/lifestyle/photos/<id>.jpg`. Drop a JPG with the matching filename into `public/templates/lifestyle/photos/` and the composer auto-upgrades that template to a real photograph.
`public/templates/lifestyle/photos/README.md` documents the filename map, recommended aspect (16:10, ≥1600 px long edge), JPEG quality (~80 %), safe-zone hint for product compositing, and licensing guidance.
Underlying `lifestyleRenderer.ts` already had the photo-first fallback wired, so renderer + thumbnail loader + template list are now all on the same source-of-truth path.
INT2 — Layer-aware tools (V1: foundation + bake-onto-active-layer)
`docs/INT2-PLAN.md` documents the full architecture, V1 vs V2 scope, and the deferred work so the next session has clear guardrails.
Image-layer kind gained optional `mask: Float32Array | null; maskW: number; maskH: number` fields so each image layer can carry its own destructive brush mask alongside its bitmap.
`Canvas.tsx` overlay render now applies the per-layer mask when present — masked pixels become transparent in the rendered output without affecting the layer's source bitmap. Off-screen canvas keeps the per-frame cost to a single `putImageData` per masked layer.
New `bakeMaskToActiveLayer(mask, w, h)` action on `editorStore` writes the supplied mask onto the active image layer. Returns `false` (no-op) when no image layer is active, so callers can call unconditionally.
New `applyBrushToActiveLayer: boolean` toggle on `editorStore` (default `false`) reserved for the V2 brush-write-path refactor.
`BrushTool` panel: when an image layer is the active layer, shows a "🖌️ Bake strokes onto <layer name>" button — user paints normally on the canvas with the existing brush flow, then bakes the resulting mask onto the layer. Existing flat-mask brush behaviour preserved.
`.nss-project` export/import now round-trips the per-layer mask + image-layer geometry (`x` / `y` / `scale`) so projects with baked layer masks survive save/open.
V2 (deferred to a dedicated session per the plan doc): rewriting `interpolateStroke` so strokes write directly to the active layer's mask in real time without a manual bake step.
EXPORT-V2 — Layer-aware export with per-layer checklist
`ExportPanel` now has TWO export modes: **Pipeline** (clean mask + filter + background — best for transparent PNG) and **Canvas snapshot** (captures the canvas as displayed, with all visible overlay layers / text / shapes / shape-fills baked in).
New "Include in export" checklist: Background / Filter / Adjustments / Layers — each can be toggled off so the export bakes exactly what the user wants.
When Layers is checked, a per-layer checkbox list appears with Select all / Select none controls. Each layer can be excluded for this export only; the working view is unchanged.
Snapshot mode temporarily toggles layer visibility to honour the checklist, waits two animation frames for the canvas to re-render, captures via `toBlob`, and restores the visibility flips so the editor view is exactly where the user left it.
Pipeline mode applies the toggle to the existing pipeline path (Background → background type / `transparent`, Filter → preset / `none`). Adjustments toggle is reserved for V2 of the pipeline (it currently always applies adjustments since they're a CSS filter step).
Editor canvas gained `data-editor-canvas="true"` so snapshot mode finds it reliably even if more than one canvas is on the page.
Browser support note for R-LANG locales
Locale string coverage has been deepened across `en` / `es` / `de` / `pt` / `ja` for the new editor / layers / AI sections.
Browser support
Tested in Chrome 124+, Edge 124+, Firefox 127+, Safari 17.4+. WebGPU recommended for fastest inference but WASM fallback exercised on all platforms.
Changeset summary
203 files touched across this sprint — 120 modifications and 83 new files.
New directories
`src/app/all-in-one/` — comprehensive landing
`src/app/api/collab-signal/` — WebRTC signalling endpoint (R-COLL)
`src/app/resources/{gif,image-upscaling,lifestyle,live-camera,pdf,video}-*/` — 6 tool-specific guides
`src/components/layers/` — shared layer architecture (LayersPanel + thumbnail + add-menu + blend-picker)
`src/components/staging/` — Scene3D + Relief3D + FurniturePalette
`src/components/editor/tools/` — Project / Tuning / Collab / Preview3D / ImageEditorLayers panels + Canvas quick-actions
`src/components/video-editor/` — VideoEditorLayersPanel + VideoCanvasQuickActions + VideoPreview3D
`src/lib/ai/` — commandBridge / goalRecipes / toolGuidance
`src/lib/commands/` — registry / executor / parser
`src/lib/collab/` — rtcSession
`src/lib/editor/` — keyboardRegistry
`src/lib/llm/` — webllmAdapter (scaffolding)
`src/lib/processing/` — 6 callable processing modules
`src/lib/project/` — export / import
`src/lib/sam/` — selectSubject
`src/lib/tune/` — tuningProfile + activeTuning
`src/lib/store/` — layerHistory
`public/staging/furniture/` — 7 stock SVG cutouts
`public/demo/` — tool-specific before/after asset pairs
Files heavily reworked (representative subset)
`src/components/editor/Canvas.tsx` — layer-aware overlay render, drag-to-position, select-subject pointer integration, layer-snapshot undo restore.
`src/components/editor/PropertiesPanel.tsx` — Project / Tuning / Collab / 3D Preview / Layers accordion sections wired.
`src/components/editor/ToolSidebar.tsx` + `MobileEditorBar.tsx` — Select-Subject tool added.
`src/components/video-editor/VideoEffectsPanel.tsx` + `VideoEditorShell.tsx` + `VideoPreviewCanvas.tsx` — Layers panel section, 3D modal listener, per-frame layer composite.
`src/lib/store/editorStore.ts` + `videoEditorStore.ts` — layer types + actions + setLayers + mergeDown + textOverlays unification.
`src/lib/ai/AiPanel.tsx` + `fallback.ts` + `tools/imageTools.ts` — goal recipes, tool guidance, layer commands, AI bridge.
`src/workers/inference.worker.ts` — TuningOverrides shape + per-pass override application.
`src/lib/hooks/useQueueProcessor.ts` + `useGifProcessor.ts` — active-tuning passthrough; GIF queue serialization.
`src/lib/project/projectExport.ts` + `projectImport.ts` — layer serialization with per-layer bitmap + mask ZIP entries.
`src/lib/image/fringeDecontaminate.ts` — `deltaE` + `forceErosion` options for tuning profiles.
`src/lib/editor/keyboardRegistry.ts` — Select-Subject + Ctrl+J / Ctrl+Shift+]/[ / Delete layer shortcuts.
`src/app/sitemap.ts` — `/all-in-one`, 7 missing tool routes, `/editor`, `/video-editor`, `/lifestyle-composer`.
`src/components/layout/Header.tsx` + `Footer.tsx` — All-in-one nav link, missing tool footer links.
`src/messages/{en,es,de,pt,ja}.json` — 25+ new translated keys per locale.
13 new + 9 newly registered help articles in `src/content/help/*.mdx` + `src/lib/content/helpContent.ts`.
`package.json` — added `three` + `@types/three` (MIT, ~300 KB dynamic-imported).
Real photography template library (R-PHOTO)
`scripts/fetch-lifestyle-photos.mjs` ships 14 themed backdrops, one per lifestyle template slug, generated via image.pollinations.ai (free, no auth, deterministic per-slug seeds). Each slug carries a hand-written prompt that describes its surface / scene (oak tabletop, marble studio, black velvet, kitchen counter, etc.) so the fetched image actually matches what the template intends to depict.
`public/templates/lifestyle/photos/<slug>.jpg` is now populated; `LifestyleComposerZone` HEAD-checks each `photoUrl` and replaces the SVG mockup automatically. Drop a curated studio shot of the same filename to override any backdrop — file system wins; the script skips existing files unless `--force` is passed.
Roadmap reflects the ship; the Next-section follow-up is replacing any of the generated backdrops with hand-curated studio shots.
Content refresh (this release)
Roadmap (`/roadmap`) rewritten: 16 items moved from Next / Later into Shipped (layers, 3D, R-SAM, R-VO V1, .nss-project, R-COLL, R-TUNE, R-LLM, goal recipes, R-BVID, GIF queue serialization, R-LANG, A1 PWA, floating quick-actions toolbar, EXPORT-V2, in-editor utilities). Next now only carries INT2 V2, R-VO V2, R-PHOTO, and the E3+X1 video-utility worker migration. Later trimmed to Real-time video effects, AI video background replacement, smart guides + layer alignment, group + clipping mask layers, and mobile-responsive editor layouts.
FAQ (`/faq`) gained 8 new entries: layers, 3D mode, .nss-project, AI assistant + LLM tiers, collaborative sessions, tuning profiles, languages, and the All-in-One landing page.
About page (`/about`): "One job, done right" principle updated to acknowledge the full suite. Model credits list rewritten — RMBG-1.4 + BiRefNet + Swin2SR + depth-anything-small-hf + @mlc-ai/web-llm with their actual licenses (previously listed a non-existent RMBG-2.0).
Story page (`/story`): new "Where it is today" section bridges the cutout origin narrative to the v1.0.0 surface (layers, 3D, AI assistant, collab, tuning, .nss-project, 30+ utilities) and links to `/all-in-one`.
Blog refresh: `lifestyle-product-photography-browser.mdx` and `real-estate-virtual-staging-guide-2026.mdx` updated to reference the layers panel, 3D view, project save, orbit recording, and the All-in-One landing.