Changelog
Release notes for the PanelWave format and this documentation site — format versions, notable additions, and documentation updates.
Release notes for the PanelWave format and this documentation site. For the format's design and compatibility rules, see Versioning.
PanelWave is live
- panelwave.org — the new PanelWave website is live: the product, the open format and player, pricing, examples and the Founding Creators programme.
- docs.panelwave.org — this documentation is public: the format reference, the player, the CMS, the AI assistant (MCP) integration and the Help Center.
- The PanelWave beta is live at app.panelwave.org. Places in the beta are given out through the Founding Creators programme (50 places, applications close 30 November 2026). Founding Creators use the Creator plan free for 12 months. The beta tag next to the PanelWave CMS wordmark stays until general availability.
- Connecting an AI assistant to
https://mcp.panelwave.org/mcpno longer asks for a beta access password — signing in with your PanelWave account is enough (AI Assistants (MCP)).
Panel stacking survives a reload, choices change variables, readers keep their language
CMS editor and publishing:
- Send to Back sticks. Arranging panels used to write a negative z-index, which the export dropped, so after a reload every panel was back at the same level. The arrange commands now renumber the page's panels to a gapless stack within the format's 0–9999 range, as one undo step and one save (Pages & Panels).
- Variable changes on a path reach the reader. Variable changes
stored on a graph edge — on choices created through MCP or imported
from a manifest — are now exported as the edge's
action, the field the player applies (Graph). - Imports keep hotspot labels. Choices of an imported manifest or work archive keep their labels and accessibility labels, and edges keep their variable changes (Import).
- Page view follows the header language. Switching the language in the editor header now also redraws the balloons in page view, and balloons of a panel selected in page view no longer disappear after you open another panel.
- MCP: outlines can branch, rejoin and end with
next, choice labels keep every language, and the work's cover no longer counts as an unused asset.
Player and reader (CMS preview and read.panelwave.org; in
@panelwave/player from the release after 1.2.0):
localeChangereports changes only. It no longer fires with the player's internalen-USdefault on load, which made hosts store English as the reader's choice (Inputs & Outputs).- The reader's language wins over the server default:
?lang=, then the language picked earlier, then the browser languages, then the work's default (What readers see). - At the 9 px lettering floor, a balloon wider than its panel re-wraps to the panel width instead of shrinking its text again.
Choice labels, hotspot buttons, lettering color — and the 1.7.0 tooling
Four optional fields were folded into format 1.7.0 before its tooling release. Existing manifests stay valid unchanged:
Edge.label— the choice text of a path, shown on the branch chooser's buttons (Graph).Hotspot.display—auto|button|area: show the hotspot's label as a button or keep an invisible click area.auto(default) shows buttons for a choice (Hotspots).BalloonConfig.textColor— the lettering color, e.g. amber on-screen text on a dark fill (Speech Bubbles).- Variable ids may use underscores, such as
trust_jonas(Variables).
Released on npm: @panelwave/types 1.2.0 (types the 1.7.0 fields)
and @panelwave/cli 1.2.0 (bundles the 1.7.0 schema; upgrade
targets 1.7.0). Update with npm install -g @panelwave/cli@latest. The
current versions of all packages are listed under
Versioning → Current releases.
- CMS: exports the new fields — Shown as on hotspots (Hotspots), the Text color in the Balloon Style panel, choice labels from the graph editor — and accepts variable ids with underscores.
- Player:
@panelwave/player1.2.0 already readsEdge.label;displayandtextColorfollow in the release after 1.2.0 and are live in the CMS preview and on read.panelwave.org.
Findings from building a branching work entirely through MCP
In the PanelWave reader and the CMS preview; in @panelwave/player from
the release after 1.2.0:
- Choices are visible. The hotspots of a choice show their labels as buttons, also on video panels. At a decision, Next opens the choice dialog instead of picking a path (Branch choices).
- Lettering scales with the page and never renders below 9 px; balloons stay inside their panel. On phones, page view uses the full width.
- The reader starts in the reader's language: the browser language when
the work has it, a language picked earlier on that device, or
?lang=in the link (What readers see).
- Pages per format. A work created from an outline gets one panel per
page on phones and several on larger formats (4 on tablet, desktop and
landscape print, 6 on portrait print, 8 on big screens), with a new page
at each choice.
pw_pages_composere-lays out one format of a chapter after a dry run and your confirmation, and warns about balloons that would overlap. pw_assets_reprocessqueues thumbnails, image sizes and video renditions again for assets that stayed processing.- Balloons created through MCP are sized to their text in the work's font; choices keep their labels and variable changes. All tools: Tool reference.
Video backgrounds
- Alt-drop swaps the picture. Hold Alt while dropping an image or a video onto a panel: the background layer shows the new asset, keeps its place at the bottom, takes its shape, and the panel is refitted in every format. Before, only images could be swapped. A video dropped without Alt was added as a small layer on top, and deleting the old picture left the panel without a background.
- Set as Background in the layer context menu makes an image or video layer the panel's background. The previous background is hidden, not deleted. It also repairs a panel whose background layer was deleted.
- A one-time hint after a plain drop onto a panel with a background explains both ways.
- Panel view lays out a video panel correctly. A panel with a video background used to be shown as if it had no picture: full frame, the video squeezed into a strip, bubbles and hotspots out of place.
See The panel background.
Edges and hotspot jumps may cross chapters
An edge's to and a hotspot goTo's to may name a panel of any
chapter of the work — a chapter transition, or a jump from the last
chapter into an endings chapter. The reader continues in the target's
chapter. entry and every edge's from stay within the chapter that
holds the graph. Earlier wording required to to be in the same chapter;
manifests don't change, and existing ones stay valid.
The schema descriptions, @panelwave/types and the player's types say
so; see Graph and
Moving between chapters.
Page view follows the reader's path
In the PanelWave reader and the CMS preview; in
@panelwave/player from the release after 1.2.0.
- Choices in page view. Panels that only some options of a choice lead to are grey placeholders until the reader picks an option; then that option's path appears. Pages made up only of panels off the chosen path are skipped when turning pages, in both directions and across chapters (Choices in page view).
- Into another chapter. An edge or hotspot jump to a panel of another chapter now switches to that chapter, so Next continues there. Before, the player kept the old chapter and showed the new chapter's entry panel again (Moving between chapters).
Building a large branching story
Graph Editor (Graph):
- Whole work (all chapters) in the Chapter dropdown shows the entire story: one row per chapter, the links between chapters, and dashed grey links where a chapter end continues with the next chapter.
- A selected panel lists its Outgoing edges (condition and delete per edge), and Connect to… adds an edge to any panel of the work, grouped by chapter. Panels of other chapters appear as ↗ Title (Chapter) nodes.
- Titles wrap onto up to three lines; from 80% zoom each node shows its panel's picture. The mouse wheel zooms toward the pointer (2%–300%).
- Simulate keeps the current panel in view, and a long path scrolls so the choices and Step back stay visible.
- Validation accepts edges into another chapter and counts panels entered from another chapter as reachable.
- Exported and published manifests keep edges into another chapter; they were dropped before.
Hotspots (Hotspots):
- Hotspots built in the editor were never saved into the work: their actions were lost and the hotspot was left out of the export. They now save, export and open for editing again. Navigate with Set Variables is published as one jump that records the choice.
- Navigate picks its target from a list of the work's panels, grouped by chapter, and stores the panel itself, so renaming a friendly ID no longer breaks a jump.
- Visible If uses the JSON Logic Rule Builder.
- The canvas label shows the label text (it read [object Object]), and a panel's hotspots no longer stay drawn over the page view.
- The action, mutation and condition dialogs are readable in dark mode.
- New guide: Building a choice.
Speech bubbles (Speech Bubbles):
- Balloon presets: define named styles under Work Properties → Typography → Balloon Presets and give a bubble one with Style preset.
- Fit height to text (one bubble) and Fit All Balloons to Text (chapter context menu) size balloons for their longest language.
- The first image of a panel no longer moves its bubbles and hotspots off the artwork, and resizing a caption that sits on a panel edge no longer runs away.
Pages and panels (Pages & Panels):
- Arrange Panels by Artwork (page) and Arrange All Pages by Artwork (chapter) pack the panels into justified rows that keep each picture's proportions.
- Frame Shape in the panel inspector crops a panel to a fixed ratio, for all page formats at once.
Script import and localization:
- Script Import offers Follow my
script: one panel per scene heading and a chapter at every
# Section, with no AI call. - The Localization Workshop extracts panel descriptions and hotspot labels. Approve MT (N) confirms all shown machine translations at once and writes them into the work.
- Translate untranslated works through a whole book: strings go to DeepL in batches of 50 and are retried when DeepL asks to slow down (before, it stopped after about 75 strings).
- The Locales button waits until the work's locales have loaded. Before, adding a language too early could replace the work's default language.
Pages and panels you can link to, and pages that look like the CMS
In the PanelWave reader and the CMS preview; in
@panelwave/player from its next release. Details in
Reader Interface.
- Cover first, then the page. A work opens on its cover and continues in page view. A reader returning to a bookmark sees the cover too, with their page behind it.
- A link for every page and panel. The address bar follows the reader:
?page=pg-D3in page view,?panel=ch1-p022in panel view. Opening such a link starts right there, without the cover. A page link opened on another kind of screen opens the page with the same panels. New player outputlocationChange, inputsinitialPageIdandinitialViewMode, and thelocationUrl/parseLocationSearchhelpers (inputs and outputs). - Sharing that works. The Share dialog shows the link to the page or panel on screen (it was empty), and its QR code is drawn in the browser instead of loading as a broken image from a third-party service.
- Language switch for translated works. The toolbar offers every language the work's text is translated into, not just the languages listed in the work's settings.
- The page's own color. The page background color fills the gutters in page view and the frame around the panel in panel view, and it switches with the page. The light-gray border around the page is gone; the page runs edge to edge.
- Navigation. Page view shows the previous/next arrows on hover like panel view. Double-click a panel to open it large, and double-click again to return to the page.
- Video pacing. Image panels between two videos on a page pause the video sequence for their display duration, so the art gets read before the next video starts. Hovering or clicking a video that is waiting plays it.
- Toolbar. A solid bar with a clear top line, a Fullscreen button, a Made with PanelWave credit and a help link to this documentation.
- Fixes. Balloon text is centered in its balloon (it could sit high when the lettering font loaded late), also in the CMS editor. The browser tab shows the PanelWave icon.
Inviting your team is one click for them
- Invitations are emailed. Invitees get an Accept invitation email. People without an account go straight to sign-up with their email filled in, and they join your team with the invited role instead of getting an empty team of their own. Resend emails a fresh link (Teams and roles).
- Role changes work. Changing a member's role on the Team page saved nothing before. Only an owner can grant Admin.
- Fixes on the Team page. Revoking or resending an invitation, removing a member and deleting a shared character no longer fail. Pending invitations show as soon as the page opens, and newly joined teams appear without signing out and in again.
- Whole covers. The works grid and the cover preview in Work Properties show the complete cover instead of a 16:9 crop (My Works).
- Translations add their language. Text translated into a language the work did not list (in the editor, by import, from the Localization Workshop or through an AI assistant) adds that language to the work, within your plan's limit, so the published work offers it (Localization).
Published works read better on every screen
Live on read.panelwave.org and in the
CMS preview. In @panelwave/player from its next release.
- The page layout that fits the screen. Page view shows the page
sequence of the authored page format that suits the
device (the phone layout on a phone, the big-screen layout on a 4K
display) and re-picks it when the window is resized. The page takes its
format's aspect ratio and fills the screen; it was a fixed 16:9 box of at
most 1400 px before. Paging continues into the next and previous chapter.
Embedders can force a format with the new
pageFormatinput (inputs). - Cover first. Reading from the beginning opens on the work cover
(
meta.cover, otherwiseextras.cover). Next leaves it, and previous on the first panel or page returns to it. It also heads the thumbnail strip and the table of contents. New inputshowCover(defaulttrue). - The author's timing. Autoplay holds each panel for its
display duration
(in page view, the sum over the page's panels). Picking a speed in the
toolbar switches to the reader's seconds per panel, and Author switches
back. Autoplay stops at the end of the work and no longer stalls after a
video panel.
secondsPerPanelnow applies only to panels without a duration and to the cover, until the reader picks a speed. - Thumbnails with artwork. The thumbnail strip and the table of contents show each panel's artwork in reading order, and the strip puts a title card between chapters. In page view a thumbnail or contents entry opens the page that shows the panel (it did nothing before), and the contents list only the pages of the format on screen. Extras linked by URL only show that image as their thumbnail.
- Faster page turns. Preloading warms the next panels or pages in reading order, also into the next chapter, at the size they will be shown, plus the first panel while the cover is up. Images are warmed so the browser reuses them, and this also works on storage without CORS headers.
- Chrome. The button that opens the toolbar shows the PanelWave icon,
and the reader no longer shows a "Made with PanelWave" pill. Player
controls use the UI font (Barlow, override with
--pw-font-ui). - Ames Pro lettering. Balloons set in Ames Pro now render in Ames Pro on read.panelwave.org and in the CMS preview, under PanelWave's font license (PanelWave's own domains only). The open-source player and exported works still do not include the font: self-hosters license it from Blambot, otherwise balloons fall back to Comic Neue (Balloon renderer).
Readers open your work on a normal web page
Publishing now puts your work on the PanelWave reader at read.panelwave.org. Readers need no account and no app. Start with the new Publishing and Sharing guide.
- Three targets in the Publish Work wizard: Public (anyone with
the link, at
read.panelwave.org/your-team/your-work), Review link (a private link for reviewers that stays the same on every republish) and Internal preview (your team only, inside the CMS). - Frozen snapshots. Every publish freezes the work as it is. Later edits stay private until you publish again, and asset links are signed each time the work is opened.
- Public address. Set the team part on the Team page and the work part in Work Properties → Metadata → Public address, which checks availability as you type. Renamed addresses forward old links, so shared links and embeds keep working.
- Share it. The success screen and the new Publishing tab of Work Properties show the reader link, an iframe embed code, a QR code (PNG or SVG) and a share menu (X, Facebook, Reddit, e-mail). Links unfurl into a preview card with title, description and cover. The My Works card menu gains Open public page and Copy reader link.
- Review links are excluded from search engines and can be revoked with Revoke & new link.
- Unpublish, history and restore. The Publishing tab lists the latest 10 publishes. Restore makes an earlier one live again without touching your editor content, and Unpublish takes a target offline.
- Paid content stays on the server. For anonymous readers, panels behind
a subscription or purchase rule arrive as locked placeholders
(
"x-locked": true) with no artwork, text or audio. Locked extras keep only their title. Age gates are enforced in the reader. Review links show the full work but still ask for the age (Monetization). - Internal preview is team-only. The Preview gains a
Working copy | Published preview switch that shows the last Internal
preview publish. Public
/preview/{token}manifest links are retired, and so is the preview's Copy URL button. To show a work outside the CMS, publish it. - Deleting an asset that a live publish still shows now says so in the confirmation: readers see missing artwork until you republish (Assets).
- AI assistants:
pw_publish_previewnow publishes the review link and returns it, andpw_publish_rollbackrestores the frozen release of an earlier publish (tool reference).
Gated panels stay gated, whichever way the reader gets there
Live in the CMS preview and on read.panelwave.org. In @panelwave/player
from its next release. Details: Paywall & entitlements.
- Page view and canvas view no longer show gated panels. The paywall was only checked when moving panel by panel, so a page, or a panel revealed on the canvas, showed content the reader had not paid for or confirmed their age for. Locked panels now render as a placeholder and repaint when access changes.
- The first panel is gated too: on the initial load, on chapter jumps
from the table of contents, and when resuming a bookmark or
initialPanelId. The age gate or paywall opens over the locked placeholder; confirming the age reveals it in place. - Age requirements combine across every rule that applies to a panel, so a chapter's free preview or a free panel rule never skips a work-wide age gate. The gate asks for the highest minimum age. The purchase and subscription part keeps its precedence (panel, then chapter, then work). The CMS preview and entitlement simulator follow the same rule.
- No leaks around the gate. A gated panel's audio stays silent until the lock lifts, and the assets of locked panels are no longer preloaded.
- Locked placeholders for panels a server stripped
(
"x-locked": true, format 1.7). They stay locked whatever the rules say. In page view the placeholder is a button that opens the age gate or paywall for that panel in place (new viewport outputlockedPanelActivate). - Chapters without graph edges follow their reading order instead of
stopping on the entry panel, and
work_completefires on the last panel (Graph). - Note for embedders: a custom
entitlementAdapterdecides navigation, not rendering. Do not rely on it to hide content: strip paid content on the server, or pass anentitlementSnapshot. - Demo app:
?entitlements=free,premium,purchased:<productId>,age-verifiedsets the reader's entitlements, using the same syntax as the CMS preview's simulator (Demo app).
Smaller improvements and fixes
- Rename teams. Owners and admins rename a team with the pencil next to its name on the Team page. Personal teams that all start as "Your Name's Team" can now be told apart.
- Large archives upload reliably. Archive imports above 16 MiB go up in 8 MiB parts, and each part is retried up to five times with increasing pauses. A single long upload used to fail on throttled storage with a misleading CORS error. The admin console's work transfer uses the same upload.
- Archive imports keep covers and portraits. The work cover, character portraits and extras images of an imported archive now point at the imported files. Before, they arrived broken or missing.
- Deleted works free their storage. When you delete a work permanently, its files are removed from storage in a nightly cleanup 7 days later. Files another work still uses are kept (Works).
Single-panel chapters are valid, and panels can carry x- fields
Format 1.7.0 (relaxing, backward-compatible with 1.6.0 — existing manifests stay valid unchanged):
Graph.edgesmay be empty. A chapter without edges, such as a single-panel chapter, is valid and follows its reading order. The property stays required. Graph.x-extension fields on panels and extras blocks, in addition to the manifest root — for example a server-side paywall view marks stripped panels"x-locked": true. Extensions.
Details: Versioning.
- CMS: exports and publishes 1.7.0 and imports formats 1.0–1.7. A
chapter without links between its panels is written with an entry-only
graph (
edges: []), and the public reader marks panels a reader has not unlocked with"x-locked": true. - Player: renders 1.7 — chapters without edges follow their reading
order, and
x-lockedpanels show a locked placeholder (Paywall & entitlements). Live in the CMS preview and on read.panelwave.org; in@panelwave/playerfrom its next release. - SDK:
@panelwave/clibundles the 1.7.0 schema and@panelwave/typestypes thex-fields onPaneland extras blocks, both from their next release.
The local MCP bridge is on npm
@panelwave/mcp 0.1.0 is published (MIT, source in
panelwave/packages).
Desktop assistants — Claude Desktop, Cowork, Claude Code, Cursor and any
other stdio MCP client — start it with npx -y @panelwave/mcp. It mirrors
every tool of the hosted server at https://mcp.panelwave.org/mcp and adds
three local tools: list files, read a script, and upload a whole folder of
artwork straight to storage (deduplicated, resumable, large files in parts).
The local tools only work inside the folders you allow in
PANELWAVE_ALLOWED_DIRS. Setup per client: Local bridge.
Published manifests are lean; archives play from disk
- Two manifest versions. What you publish (and what a preview link serves) is now the lean player version: no editor-only state, no translation-workflow data, no asset-library folders, no assets that no panel uses, no strings in languages the work does not offer. For a typical work that halves the manifest. Asset links stay signed. The work archive keeps the full-fidelity version.
- Friendly panel ids everywhere outside the editor. Published manifests,
archives and exported JSON key panels by their short
friendly id (
ch1-p022) instead of internal database ids. New panels get one automatically; older panels receive theirs on the next publish or export. - Playable archives. The archive's
manifest.jsonpoints at its files inside the zip, so an unzipped archive plays from any static web server. Importing it keeps the friendly ids and re-points translations at the new copies. - Smaller media. Images ship as their full-size WebP rendition and videos as the H.264 rendition instead of the original uploads; video posters are signed like every other asset.
- New check:
UNREACHABLE_PANELSwarns when panels cannot be reached from a chapter's entry panel. - Fixes: page layouts written by the script importer now reference the right panels in exports; character names saved as the literal text "undefined" by an older editor are ignored.
- Player: relative asset URLs resolve against
assets.baseand then the manifest's own URL (rule) for images, video, posters, thumbnails, portraits, extras and plugins — via the newAssetUrlService. The per-componentbaseUrlinputs are gone. Ships with the next player release. - Profile: name, location, website and bio are always editable; Save and Cancel appear once something changed (Account).
Claude, ChatGPT, Cursor and other AI assistants can now work in PanelWave
PanelWave has an MCP server at https://mcp.panelwave.org/mcp. MCP, the
open Model Context Protocol, is how AI
assistants work with other applications. Connect an assistant once and ask
it, in plain language, to do what you would otherwise do by hand in the
editor. Start with AI Assistants (MCP).
What an assistant can do — 81 tools, listed in the tool reference:
- Script to work in one step. A work (or more chapters) from an outline: chapters, pages per format, panels with titles and descriptions, characters, speech balloons, optional choices and variables. A dry run shows the plan first; the story graph is linked so every chapter is playable.
- Artwork. Upload images, video and audio (large files in parts, files already in the library are reused), organise folders, and attach artwork to many panels at once by file name — each panel fits itself to its image on every page format.
- Editing. Works, chapters, pages and panels (create, update, reorder, move, duplicate, delete), layers, speech balloons (also many panels at once), hotspots, characters, variables and the story graph.
- Languages. Add languages, extract texts, machine-translate (drafts stay marked for review) and write translations back.
- Checks and release. Preflight validation with extra lints, automatic fixes with undo, a preview link to read in the player, publishing and rollback; background jobs such as transcoding and image optimisation can be followed.
- Answers. Outlines of a work, missing artwork, plan limits and usage, reader analytics.
How to connect: add the server as a connector in
Claude (claude.ai, Desktop, Cowork) or
ChatGPT, or in
Claude Code, Cursor, VS Code and other clients.
Sign in to PanelWave and choose the permissions on the new consent screen.
Scripts and clients with static headers use a personal access token instead.
The open-source local bridge
(@panelwave/mcp on npm) lets desktop assistants read
scripts and upload whole folders of artwork from your computer.
You stay in control:
- The assistant works as you — with your team role, your plan limits and only the permissions you granted; it does not even see other tools.
- Deleting chapters, pages, panels, characters, assets or folders, moving a work to the trash, publishing to production and rolling back need your confirmation, asked in the assistant's own dialog where it supports that.
- Profile → Connected apps & access tokens lists every connected app and token, with its permissions and last use. Disconnect or revoke at any time; a password change or password reset ends all connections.
- Every tool call is logged with the app, the work and the outcome — never the text you sent.
For developers: stateless Streamable HTTP, MCP revision 2026-07-28 with support for 2025-06-18 and 2025-11-25 clients; OAuth 2.1 with PKCE, dynamic client registration and client ID metadata documents; tools declare output schemas and return structured content. Tokens issued for the MCP server are accepted only through it, not by the CMS REST API directly. See the developer FAQ.
MCP access is included in every plan during the beta. While PanelWave is in closed beta, connecting asks for the beta access password in the browser before the sign-in.
Clicking through panels no longer mixes them up, and exports are easier to find, name and trust
- Panel switches keep panels apart. Clicking from panel to panel could save one panel's layers, speech bubbles or placement into the next one. Opening a panel no longer counts as an edit, and only the panel you are working on is saved. Clicking a panel of another page in the structure tree or the timeline opens that page and the panel, and a reload restores it. Pages & Panels.
- Exports screen. Select Work lists all your works (it showed two
placeholders), job cards show the work name again, and a new
Archive (.zip) card queues a full-work archive — one work or in batch.
Downloads are named after the work and the time, e.g.
TARMAC-Pilot_2026-09-30_18-45.zip, instead ofexport.zip. When the export service is unavailable, a job fails right away with the reason and a Retry button instead of hanging in Queued and blocking your five export slots; expiry reads "in 6d". Exports and Import pages have a ← Works link. Export. - Only your team's works can be exported — any signed-in account could start an export of any work before.
- Assets. Replace File regenerates every variant from the new file. Deleting an asset that is still in use asks a second time and names where it is used. Assets.
- Languages: adding a language beyond your plan's allowance is refused with a message naming the limit (the workshop skipped that check). Localization.
- Work properties: the localized Name is the work title — renaming it changes the published title; the fields offer only the work's languages. Works.
- Tools panel: the Text tool uses the font, size and colour set there; the Speech Bubble tool explains that balloon typography comes from the work, character and bubble styles. Editor layout.
- Smaller fixes: the Backstage breadcrumb shows the work title instead of
"Untitled Work"; Preview shows the work ID again and copied player links
carry it; panels created by dropping an image are titled with the file name
(without extension) in the work's default language, so the Graph Editor
labels them properly; a tag still typed in the new-work wizard is kept on
Create Work;
Esccloses the Track Editor; the Track, Variant and Animation dialogs and the Performance tab follow the light/dark theme; rollback reports success again.
Panels animate their layers, works can carry several alternate covers, and a character sheet can show a whole cast
Format (merged into 1.6.0 — the version number does not change, existing manifests stay valid):
- Layer keyframe animations.
Panel.animationsgainskeyframes(layerId,property,timeMs,value, optionaleasing/id),loopandname. Nine properties: opacity, position, scale, rotation, blur, brightness, contrast, saturation. Offsets are fractions of the panel size, blur is measured at a 1024 px wide panel — animations look the same on every screen. Animations. - Several alternate covers.
extras.alt_coveris one block or an array. Extras. - Ensemble character sheets. A sheet lists its characters in
characterIds;characterIdstays for single sheets and as the first entry. Extras.
Player (merged, not yet released — ships with the @panelwave/player
release after 1.2.0; 1.2.0 itself does not contain it):
- Plays layer keyframes in panel view, page view and canvas view: start when the panel comes into view, hold / interpolate / loop as the format defines, end state for readers who prefer reduced motion.
- Shows every alternate cover and the names of all characters of an ensemble sheet in the extras viewer.
- Small screens crop around the focus rect. In panel view a panel larger
than the screen still fills it, but the crop is centred on the panel's
minimalFocusRect(of the format closest to the screen's shape) instead of the panel centre. Panels. - Viewport moves render.
startViewportRect/endViewportRectwere in the format since 1.0 but the player ignored them. The artwork — layers, hotspots and speech bubbles together — now pans and zooms inside the panel box, on the same timeline as the keyframes. Animations. - Panel animations are clipped by the panel box (a layer sliding in from outside used to be drawn over the panel's surroundings in panel view), a layer keeps its own opacity while its other properties are animated, and autoplay waits for a non-looping animation to finish before it advances.
CMS:
- Animations are saved, published and playable. The Animation Editor's keyframes used to be lost on reload and never reached the manifest. They now persist, export and play in Backstage → Preview. Movement is entered as a fraction of the panel size (it was labelled pixels). Animations & Timeline.
- New preflight warning
ANIMATION_UNKNOWN_LAYERfor keyframes whose layer was deleted. - All alt covers are exported (only the first one was), and a character sheet can link several characters. Extras.
- Readable asset IDs. New uploads get an ID from their file name
(
wiesn-uebersicht-final-01) instead of a hash; existing assets keep theirs. Assets. - Page ids keep their letter. Every format has a permanent letter
(
pg-A1A4 portrait,pg-D1desktop,pg-M1mobile, …), so reordering pages no longer re-letters another format's pages. Works published earlier get new page ids once, with their next publish. Pages & Panels. - The panel's Minimal Focus Rect can be cleared per format.
- Uploads during a processing outage catch up on their own. A file uploaded while background processing was unavailable used to stay without thumbnail and size variants until someone pressed Generate. Its job is now kept and processed as soon as processing is back. Assets.
@panelwave/types and @panelwave/cli carry the additions on their main
branches; until their next npm release, the published CLI validates against
the earlier 1.6.0 schema and rejects the new fields.
An end-to-end pass through the whole authoring flow, and what it fixed
One work was built from an empty account to a published preview, and every defect found on the way was fixed. The ones authors would have noticed:
- Editor. Panel position and size typed in the Inspector are saved (they were lost on reload); Lock Aspect Ratio works; a new work opens in its own default format; context menus close on Escape and follow the arrow keys; the header no longer overlaps at medium widths; ruler labels stay readable at low zoom; panels created in the New Panel dialog keep their id and land in a free slot; the Unassigned list follows story order.
- Panel settings that did nothing now work: Allow Page View / Allow Panel View and Minimal Focus Rect are saved per format, and content warnings and the memory hint reach the manifest. Reading Order is shown read-only (it follows the panel order).
- Speech bubbles. Bubbles are no longer lost when their panel is clicked again; Visible / Locked, Audio, Generate TTS and Visible If are wired up; a locked bubble stays selectable but cannot be moved; the editor warns when balloon text is cut off; bubbles sit on the artwork in portrait formats.
- Variants. A condition typed in JSON mode is applied without the extra Apply JSON click, and variants with such conditions can be created.
- Characters. The balloon style chosen while creating a character is saved; names and bios use the work's own locales.
- Localization. Editing in German writes
de-DE(the work's locale), notde; renaming a chapter in the tree keeps its translations; untranslated cells no longer show "undefined". - Extras. An extra's default-language title survives translation; the translation locales are the work's locales; the Reader Preview's bar is clickable.
- Work Properties. Works created with the wizard can be saved; the dialog is readable in the light theme; name and description offer the work's locales; the cover chooser shows file names.
- Assets. The library shows images that have no previews yet (for example after an upload while processing was down) and regenerates them with one click; the asset picker opens above side panels.
- Publishing. The work cover and publishing metadata (series, issue, publisher, release date, copyright, license) are in the manifest; attributed speech bubbles no longer fail schema validation; the publish summary counts images at their shipped size; preflight names the file in alt-text and size issues.
The player installs on Angular 21 and 22 and ngx-translate 18, and panelChange tells you which panel
Released on npm as @panelwave/player 1.2.0 on 2026-09-29
(npm install @panelwave/player@latest).
- Angular 21 and 22. The
@angular/core/@angular/commonpeer range is now^20.0.0 || ^21.0.0 || ^22.0.0(1.1.0 declares^20.0.0, which makes npm refuse the install on newer apps). The package is still compiled with Angular 20 in partial mode; fresh Angular 20.3, 21.2 and 22.2 apps are verified in CI — strict-peer install, production build, headless render, zone.js and zoneless. No library code changed. Installation. - ngx-translate 18.
@ngx-translate/coreis^17.0.0 || ^18.0.0. Register it withprovideTranslateService({ loader: {provide: TranslateLoader, useClass: YourLoader} })— this form works on 17 and 18, whileTranslateModule.forRoot()no longer exists in 18 and 18'sprovideTranslateLoader(Class)breaks minified production builds for a plain class. Application setup, troubleshooting. panelChangecarries the panel id. The payload is the new exportedPlayerPanelChangeEvent—{ panel, chapter, panelId, previousPanelId? }.panelIdis the panel's key inchapter.panels(Panel.idis optional in the format and usually absent, so hosts no longer look it up by object identity);previousPanelIdis unset for the first panel after a load or reload. Additive:panelandchapterare unchanged.panelis the manifest panel as written — variants are not resolved in it (the previous docs said otherwise). Inputs & Outputs, Saving Progress.- Consumer smoke test.
npm run smoke:consumer -- --angular <major>packs the library into a fresh app of that major and renders the demo work; CI runs it for 20, 21 and 22. Development & Contributing. - Docs. The
Panelexample in the package README read$event.panel.id, which did not compile; it now reads$event.panelId. The setup notes mentionallowedCommonJsDependenciesforjson-logic-js.
Move chapters, pages and panels for real, delete panels without losing them elsewhere, rotate on the canvas board, and see whether a canvas reads on a phone
- "Move to…" works for chapters, pages and panels in the structure tree (it used to say coming soon). The dialog offers only valid destinations: a position among the chapters, another chapter for a page, a page of another chapter for a panel. A page takes its panels along; a page or panel moved to another chapter is taken off the source chapter's other formats' pages, its canvas layout and its graph — and Undo puts all of that back. Dragging a panel onto another chapter's page now goes through the same path (it used to leave the panel's chapter, other pages and edges dangling). Move to….
- Rename in the panel context menu; collapsed chapters stay collapsed across renames, new panels and page reloads (per work, for the browser session). Context menus.
- Canvas delete keeps panels other formats still place. Deleting a panel on the page canvas that another page or format still uses only removes it from the open page, with a toast saying where it is still used; the tree's Delete Panel deletes everywhere and its confirmation lists the affected pages and formats. Both are one undo step; the legacy page references of older works are cleaned and restored too. Deleting panels.
- Rotate handle on the Canvas Layout Board. A knob above the selected panel rotates it around its origin, Shift snaps to 15°; the inspector gets a Rotation (°) field and Reset rotation. Saved with the placement and rendered by the player. Canvas Layout Board.
- Phone ribbon. A toolbar toggle overlays the column a portrait phone reads and judges the layout column-friendly or not, live: panels that leave the band and trail steps that read upward are outlined, and a verdict chip counts the phone screens. View-only, remembered per browser. Phone ribbon.
- Nudging fixed. Arrow keys moved a layer 3 px and Shift+Arrow 30 px because the key reached the editor three times; it is 1 px and 10 px again, and speech bubbles and hotspots nudge too (each an undo step). The same fix stops Ctrl+Z / Ctrl+Shift+Z from undoing twice, and Ctrl+D makes one copy instead of two. Moving and resizing, Keyboard Shortcuts.
- Preview explains empty works. A work with no chapters, or none with panels, shows Nothing to preview yet and what to add instead of a raw player error; chapters without panels are left out of the preview and counted under the device frame. Preview.
- Accessibility and speed. Higher-contrast text on the editor header's yellow accent, a proper tab list for the editor tabs, accessible names on editor, timeline, canvas, team and export controls; the Characters page serves thumbnails instead of the original portraits, work cards reserve their 16:9 cover space, and the profile lists the 10 newest sessions with Show all. Characters, Works, Active sessions. Node ids and the selected item in the structure tree and clip titles on the timeline are readable in every theme, and a video panel's play / pause / stop bar keeps its size at any canvas zoom instead of shrinking to tiny buttons. Video panels.
- Shortcuts after reopening the editor. After you left the editor and opened it again — for example to switch works — keyboard shortcuts could still act on the editor you had opened first. Each visit now has its own shortcuts, and the editor no longer slows down over a long session.
Read-only works hide their write actions, the preload setting is yours to edit, archives carry bubble audio, and page imports settle their credits
- Read-only works, everywhere. A work above the plan limit or of a suspended team now shows the Read-only banner in the Backstage tools as well as the editor, and hides or disables every write action instead of failing it: no uploads, folder actions, new chapters, drag reorders or panel adds in the editor; no add / edit / delete / reorder in Characters, Extras, Localization, Audio and Paywall. Any write that still slips through is refused with one Read-only toast. Export, archive, trash and comments are unaffected. Read-only works, Plans & Limits.
- Editable preload settings. The inspector's Perf tab's preload block
is a form — strategy (None / Lookahead / Aggressive), panels ahead (0–20),
parallel downloads (1–16). Changes update the estimates at once, are
saved to the work and exported as
settings.preload; JSON and archive imports restore them (out-of-range values are dropped). The Performance tab, Import. - Work archives carry speech-bubble audio. Uploaded voice lines and TTS output per language travel in the archive with their files and are re-attached to the same bubbles on import; tracks whose bubble or file is missing are skipped and counted. Archives made before 28 September 2026 carry none. Archive export, Importing a work archive.
- Page Import. The import step's progress bar now moves (it sat at 2 % until done); the upscale credit reservation is settled after every import, including when upscaling could not run; Cancel import during the import step really stops it and removes the empty new work it had created; Discard releases the reservation; and sessions idle for 30 days are discarded by the daily cleanup with their credits released and an empty new work removed. Upscales also run in parallel now. Running an import, Upscaling and credits.
A paywall rule can name every product that unlocks it, and readers see each product's name and price
requiredProductIdson paywall rules. A purchase rule can list every product that unlocks it. Owning any one of them is enough, and the player offers one Buy option per product. Paywall → Product lists.paywall.products. Describes the products and subscription tiers that rules reference by id: localizednameanddescription,price,type. The player labels each Buy / Subscribe option with the product's name, description and price in the reader's language, falling back to the rule's name and price. Paywall → Products.- Additive. Every 1.5 manifest stays valid. Versioning.
- CMS export. Rules export all their unlocking products (previously only
the first), and each product's name, description and price go into
paywall.products.requireEntitlementstill names the first product, so older players keep working. Import accepts formats 1.0–1.6. How the paywall reaches readers. - Tooling. Released on npm:
@panelwave/types1.1.0 and@panelwave/cli1.1.0 (bundles and targets 1.6.0),@panelwave/player1.1.0 (labels Buy / Subscribe options frompaywall.products). CLI 1.0.0 still validates against 1.5.0 and rejects the new fields — update withnpm install -g @panelwave/cli@latest. CLI.
Inputs apply after init, paywall scopes and age checks work as specified, and the overlay offers Buy / Subscribe
Released on npm as @panelwave/player 1.1.0 (npm install @panelwave/player@latest).
- Inputs can change after init. A new
manifest/manifestUrlreloads the work (position, non-persistent variables, overlays, variant overrides and autoplay reset; the previous analytics session is closed), andreload()is public. A newentitlementSnapshotre-evaluates the gates (removing it makes the reader anonymous).locale,viewModeOverride,showToolbar,autoplay,secondsPerPanelandreducedMotionapply live. Inputs & Outputs. autoplayinput works. It starts autoplay once the work is ready; the reader's toggle takes over from there.- Table of contents and thumbnails with
manifestUrl. Both now list the work however it is loaded. Quickstart: Embed. - Chapter and extras paywall scopes. A
chapterrule gates only the chapter inrefId(its free preview counted within it) and wins over a work rule for its panels. Anextrasrule never gates panels; it locks its extras item. New exportsisExtraLocked,chapterOrderFromManifestandPaywallService.isExtraLocked(). How rules are evaluated. - Age on top of payment. A rule that combines an entitlement with
ageGate/minimumAgenow requires both: the reader answers the age gate first, then sees the paywall. Before, a rule with a customrequireEntitlementkey and an age unlocked after the birth date alone, and purchase or subscription rules ignored their age. Age gates. - Buy / Subscribe on the paywall overlay. Options come from the blocking
rule (its product or tiers, with name, description and price); Sign in
stays.
paywallActionis now{ action, gate, productId? }with'purchase'and'subscribe', andPaywallGategainsruleId,lockReasonandoptions. Buy and Subscribe options. - Breaking (types):
PurchaseInfo.priceis optional. Code that readsoption.price.amountmust handle a missing price. - Edge mutations wait for the gate. A move blocked by the paywall or age gate no longer changes variables, and canvas taps now apply edge mutations. Mutations.
- Gates hold the story. Arrow keys,
Tand swipes do nothing while the paywall or age gate is open; Escape dismisses the paywall or closes the age gate and the reader stays put. Keys in a select no longer reach the story. Input methods. - Translated gates and chooser. New UI keys
age_gate.*,branch_chooser.*andpaywall.reason_*(add them if you ship your own translation files); month names viaIntl. Localization. - Choices only when there is a choice. The button appears when at least two paths are open. Branch choices.
- Bundle budget measured as shipped. CI checks the 180 KB budget against the minified + gzipped bundle, about 106 KB today. Development & Contributing.
Gate a single chapter or bonus item, name the product that unlocks it, and publish rules the player can enforce
- Chapter and Extras Item rules. The paywall editor's scopes are now Work Level, Chapter, Panel Level and Extras Item; Chapter and Extras Item rules need a picked target. A chapter rule's free preview counts panels within that chapter; an extras rule locks only its item. Old Global rules behave as Work Level rules. Creating a rule.
- Unlocking products and an optional age on any rule. Purchase rules list the products that unlock them (none checked: any purchase), and every rule can add a minimum age that readers must pass in addition to paying.
- Published rules the player can enforce. Exported rules are schema-valid:
chapter, extras and panel rules carry their target, a purchase rule names its
first unlocking product (the reader's Buy option, with the product's price
as fallback), and the age travels along. Rules with a missing target are left
out and flagged by the new
PAYWALL_TARGET_MISSINGcheck (an error for active rules). How the paywall reaches readers. - The simulator tests your work's own rules with the player's logic, including chapter previews, locked extras items and age plus entitlement. Simulating reader access.
- Work archives carry rule targets and unlocking products and remap them in the copy.
- Panel audio plays in published works. Exported manifests now include panel audio and audio layers with their asset references, so the player can play them. Audio.
Import any 1.x manifest up to 1.5, see every issue, control large uploads, and export videos with their panel audio
- JSON import accepts formats 1.0–1.5, including patch and pre-release
versions, so CMS exports import back. Newer formats get "This manifest uses
format X; this CMS supports 1.0–1.5." The import now also brings settings
(style and output presets, video UI defaults), canvas layouts, asset folders,
the localization block, sequence audio tracks and typed extras, with every
reference remapped, and re-importing a CMS export no longer duplicates hotspot
edges. Paywall rules, tracking and
uiare not imported. Import. - Preflight lists logic issues. A new Logic group shows the
VARIANT_*issues (two of them block publishing), and an Other group catches anything uncategorized, so the list always matches the summary. Validation & Preflight. - Pause, resume, retry and cancel large uploads. Files of 10 MB and more appear in a Large uploads section of the Assets tab with status and progress. Pause keeps finished parts; Retry continues where it failed (or restarts if storage dropped the upload); Cancel cleans up storage. A page reload still discards unfinished uploads. Large files.
- Video export with the work's panel audio. Include audio narration is now Include panel audio (voice-over, sound effects, music) with per-role toggles. Panel audio follows its panel, loops carry across panels that share them, and sequence tracks play across their chapter with volume, fades, speed and loop. Unusable files are skipped; existing presets keep working. Export.
- Frame rate is honoured. Video exports use the chosen frame rate; every video used to render at 30 fps.
- Privacy dialog corrected. The in-app privacy summary now matches the published policy (hosting in Germany, the actual service providers, self-hosted error reporting).
The open-source layers are on GitHub, and the SDK and player install from npm
- Public repositories on GitHub. The format, player, and SDK moved to
github.com/panelwave:
panelwave/schema (CC BY 4.0),
panelwave/player (MIT), and
panelwave/packages (MIT;
@panelwave/typesand@panelwave/cli). Report bugs in the matching issue tracker. Introduction → Open source. - Install from npm.
@panelwave/types1.0.0,@panelwave/cli1.0.0, and@panelwave/player1.0.1 are published, so the build-from-source workarounds are gone:npm install @panelwave/types,npm install -g @panelwave/cli,npm install @panelwave/player. CLI installation, Player installation. - Verifiable releases. Every package is released from its repository's GitHub
Actions
releaseworkflow via npm trusted publishing, with a provenance attestation that links each version to the commit it was built from. - The CLI's bundled schema is guaranteed current. The CLI validates offline
against its own copy of the schema. The SDK build fails if that copy drifts from
panelwave/schema, or if
upgrade's target version differs from the schema's declared version. The current release bundles and targets format 1.5.0. CLI → Bundled schema. - Schema URL clarified. The
$idhttps://panelwave.org/schema/1.0/panelwave.schema.jsonis an identifier and isn't served publicly yet. Get the file from panelwave/schema or use the CLI's bundled copy. Validation.
The player is released: install it from npm, try it in the browser
- On npm.
npm install @panelwave/player @ngx-translate/core. Version 1.0.1 is current. Setup (providers, UI translation files, balloon fonts): Installation. - Open source on GitHub. The player lives at github.com/panelwave/player under the MIT license. Every push runs lint, unit tests, the Playwright suite and a 180 KB (gzipped) bundle budget. Development & Contributing.
- Live demo. panelwave.github.io/player runs the latest build and is redeployed on every push. Load your own manifest, preview phone/tablet/desktop frames, or open the dev tools. Demo App.
- Escape closes the open dialog. With a dialog open, Escape closes the
topmost one (the language picker included), and arrow keys and
Tno longer reach the story behind it. Escape only hides the toolbar when no dialog is open. Input methods. - One balloon engine for editor and reader. The CMS editor now holds the master copy of the speech-balloon engine and the player a synced copy, so balloons render identically in both. Balloon Renderer.
See what readers download before you publish, and keep working when a work goes read-only
- Performance tab in the inspector. The new Perf tab estimates the download size, requests and decoded memory of the open panel (or the whole page in page view) at 1×/2×/3× screen density. It also shows load times on Slow 3G, 4G and Wi-Fi with and without preloading, and suggests fixes: heavy originals, missing responsive variants or poster frames, memory and layer budgets. The Performance tab.
- Read-only works open again. Works above your plan's publication limit (or of a suspended team) can be opened, previewed and exported again. The editor shows a Read-only banner and stops auto-saving instead of raising a permission error on every edit, and the Localization Workshop opens without an error. Read-only works.
- Stale page references are found and fixed. The new
DANGLING_PAGE_REFcheck finds pages that still list deleted panels (the timeline's Panel not found). Fix cleans up that one page, and Undo puts it back exactly. Dangling page ref. - Preflight Fix buttons work. Fix on broken links and empty panels had silently done nothing. It now applies, and can be undone. Auto-fixes.
- Canvas board: a minimap; deleted panels no longer leave a stale placement behind; and two new warnings, for paywalled panels visible in the overview and for low-resolution artwork. Publish checks.
- Graph editor: every panel of the chapter appears, so a new chapter's first edge can be drawn. Edge conditions now save and reload, and clearing one removes it. New edges no longer duplicate on Save. Validation shows the server's findings with panel titles. Edge conditions.
- Variant conditions list your variables. The variant editor's variable dropdown now offers the variables from the Variables designer instead of a single bogus entry. Variants.
- Structure tree: the panel Move to... dialog lists every chapter and page again (it was always empty).
- Code reference now covers every canvas and variant check. All codes.
- Publish status and release history show their data again. The publish wizard's progress and the release history list had shown blanks. Publishing.
Find your exports from anywhere, and a fair share of the API for everyone
- Exports screen reachable. The user menu (your avatar, top right) has a new Exports entry that opens the full screen with per-format options, presets and the job list. It replaces the old Settings entry, which sent you to the sign-in page. The job list's status and type filters now actually filter, and job cards show their details instead of blanks. The Exports screen.
- Read-only works export too, including as an archive; only editing stays blocked. Export limits.
- Request limits on every endpoint. Each account and address gets a generous request budget. Going over it answers "Too many requests. Please try again in N seconds." Sign-in is limited to 5 attempts per 15 minutes per account, and password-reset emails to 3 per hour. Previously, one shared sign-in limit applied to the whole platform. Too many requests.
Richer extras, interactive canvas hotspots, and a player that respects motion settings
- Extras show their real media. Extras now show image galleries with thumbnails, videos with posters, audio tracks, and PDF/text documents with an Open document link, instead of an empty image. The Other filter works. Modals and overlays.
- Hotspots work in canvas view. The current panel's hotspots respond to
click, tap and keyboard exactly as in panel view (tracked as
hotspot_click); hotspots on neighbouring panels stay inert. Canvas View. - Reduced motion from every source. Transitions and camera glides now
honour the OS
prefers-reduced-motionsetting and the reader's Settings switch, not only the host'sreducedMotioninput. Accessibility. - Translated toolbar, comments and paywall. Toolbar labels and tooltips, comment timestamps and the paywall overlay use the UI translations (English and German ship with the package). Localization.
- Faster first panel. The artwork on screen loads eagerly at high priority; other panels stay lazy. Performance.
- Plugin host hardening. Messages are accepted only from a plugin's own
iframe and origin, replies target that origin, and same-origin plugins lose
allow-same-origin. Security model. - Demo app tools. A manifest selector (bundled works, any URL, or a local file), responsive preview frames, and a dev-tools drawer with a variable inspector, event log, FPS/heap metrics and a debug overlay. Demo App.
- Fixes:
panelChangefires once per navigation; hosts used to receive every change twice.- The Settings modal edits a working copy that Cancel and Escape discard.
- Share reports native sharing correctly.
- The table of contents follows manifest changes, and Enter navigates once.
- The thumbnail strip scrolls to the current panel.
- The age gate rejects impossible dates.
- Balloon
curveAmount: 0andmaxWidth: 0(natural width) are honoured.
Big files upload, exports show your actual art, and archives move whole works, paywall included
- Uploads of 10 MB and more work. Large video and audio files now go straight to storage in 5 MB parts, with automatic retries for each part. They then join the library like any other upload: checked, deduplicated, processed, and filed into the selected folder. Large uploads used to never reach the library, so re-upload any that went missing. Large files.
- Upload checks. The CMS now checks what actually arrived. A file whose content doesn't match its type is rejected, SVGs with scripts or embedded HTML are refused, and storage sizes are measured on the server. A rejected Replace File leaves the original untouched. Upload checks.
- PDF and PowerPoint exports show your artwork. Exports of current works used to have no images, lost text layers and printed garbled bubbles. Each panel now carries its visible art, text in the default language, and bubbles labelled with the speaking character, and PowerPoint embeds the images. PDF and PowerPoint.
- Video panels in the video export. Panels with a video layer play their clip, looped or cut to the panel's display duration; other panels show their artwork as a still. Everything is letterboxed to the chosen resolution. Video.
- Work archives carry paywall rules. Every rule, live or draft, is in the archive and arrives disabled. Its settings are kept, its locked panels are remapped, and a note explains where it came from. Paywall rules arrive disabled.
- Archives up to 50 GiB. Import Archive switches to a part-wise upload above 1 GiB; the previous ceiling was 5 GB. Importing a work archive.
- Page Import housekeeping. Page images of sessions abandoned for 30 days are cleaned up. When you append to an existing work, your edit rights are checked again at Import. Limits and quotas.
- Accessible Backstage. All 14 Backstage screens pass an automated
WCAG 2.1 AA check:
- Icon-only buttons are named after their tooltip.
- Dialogs take focus, close with Esc and return focus to where you were.
- Clickable tiles work with the keyboard.
- Light-theme primary and muted text colours have more contrast.
- Fixes: re-uploading the original file of a replaced asset no longer fails with a server error; it becomes a separate asset. A balloon Curve Amount of 0 now really draws a straight tail (Speech bubble style). Both CMS web apps send standard browser security headers.
Age gates, bookmarks and choices, and loading a work by URL
- Age gate. Paywall rules with a minimum age now ask for a birth date in
the player instead of showing the purchase overlay. A pass is remembered on
the device, the reader continues where they were going, and hosts get an
ageVerifiedevent. Age gates. - Like and bookmark work. Both are stored per work on the device, tracked,
and emitted as
likeChange/bookmarkChange. A bookmark is resumed on the next visit when the host passes no start position. Like and bookmark. - Branch chooser. When a panel has several outgoing paths, the toolbar's
Choices button lists the ones currently open and follows the chosen edge
with its transition and variable changes (tracked as
branch_choice). Branch choices. manifestUrlworks.<pw-player-shell manifestUrl="…">loads and validates the manifest itself; the "not implemented" error is gone. Quickstart: Embed.- Edge actions apply. Variable mutations on graph edges now also run on ordinary Next navigation. Mutations.
- Paywall integration documented. Supply
entitlementSnapshot(orentitlementEndpoint+readerToken), handlepaywallAction, and callrefreshEntitlements()after checkout. Paywall & Entitlement.
Arrange several panels at once
- Stacking order for the whole selection. Bring to Front / Forward / Backward / Send to Back apply to every selected panel and keep their relative order. Stacking order and matching sizes.
- Match Size. Match Width, Height, or both copies the primary panel's size onto the other selected panels and keeps them on the page.
- Work Properties use full locale codes. The Localization tab lists
en-US,de-DEand so on by name, like the rest of the CMS. Values saved under bareen/dewere converted automatically. Localization. - Themed tooltips everywhere, including Localization, Characters, Products and all shared dialogs.
- Security clean-up: two old development endpoints that could hand out upload links into asset storage without signing in are removed. The app never used them; uploads only go through the signed-in upload flow.
PanelWave CMS is marked as a gated beta
- A small beta tag now sits next to the PanelWave CMS wordmark in the editor, Backstage and sign-in screens. Editor Layout.
Translate in the order the story is read — from the language it was written in
- Strings list in story order. Extract Strings now walks the work the way a reader does: work title, then each chapter's title and its pages in order, each page's panels in reading order (title, then bubbles), panels not placed on a page, and character bios last. Keys embed panel ids, so the previous category-then-key order shuffled bubbles at random. Existing works pick up positions on their next Extract Strings run; until then their strings list last.
- Sortable Key / Default Text / Translation columns. Click a header to sort, again to flip; untranslated rows sink to the bottom when sorting by translation, and a Story order button restores the default. A "Showing N of M strings" line appears while a filter is active. The translation editor.
- Machine translation uses the real source language. Translate untranslated into a locale the workshop believed was the default sent identical source and target languages to the provider, which echoed the input back — the German column filled with English. The source is now resolved explicitly (work default → Work Properties hint → the locale with the most human-entered values), the per-string source text is always human-entered and never the target or a machine draft, and translating into the default language picks the best other locale. A provider failure stops the run with a warning and the partial result instead of silently writing placeholder text. Machine translation.
- Extraction no longer flips the source language. After confirming German translations, a re-extraction could turn the Default Text column German and flag every string stale, because the source locale was guessed from the first key of the title map. The source is now resolved the same way as above, and a previous default text that matches one of the entry's own translations no longer counts as a source edit — a genuine edit still marks the entry Stale.
- Backstage layout: Entitlement Simulation gained the standard page wrapper, and the workshop's actions column is wide enough for the five per-row buttons.
Moderate your team's comments yourself, and see at a glance where the discussion is
- Comments post immediately. Authors are already members of the work's team, so the email-verification gate is gone — a new comment is approved on creation unless the content guard (link cap or blocklist) holds it for review.
- Moderation views in the CMS. Owners, admins, and editors get Discussion / Review queue / Rejected tabs in backstage and in the editor drawer, with status badges and Approve, Flag, Reject, and Restore actions. Nothing is deleted by moderating. Moderating as a team.
- Count badge on the editor's Comments button. It shows the approved comments for the drawer's current target (selected panel, else page, else work), turns amber while comments await review, and refreshes on selection changes and when the drawer opens or closes.
- Fixes: the comment thread loaded through the dev proxy 404'd
(query parameters were joined with a second
?) and pagination totals were undefined (unquoted struct keys uppercased by Lucee 6.2); the drawer now follows the app theme in dark mode, shows the signed-in user's initial (not the first character of their id), and renders author avatars.
Help where you need it, and speech bubbles that keep every language
- Contextual help icons. Every Backstage tool, the works list, and the editor's inspector, left sidebar, and timeline carry a help icon that opens the matching page of this documentation in a new tab; the inspector's follows the active tab. The user menu's Documentation entry leads to the CMS overview. Contextual help.
- Speech-bubble text is kept per locale. The editor held one string per bubble, picked from the stored translations without a locale preference (so a single German translation showed up in the English view), and wrote that string back over every other language on the next autosave. Bubbles now carry their full translation map; the canvas, inline editor, and Inspector show the editing locale, the header locale switch redraws every bubble, edits touch only the edited locale, and a blank edit never creates a key. Dialogue in multiple languages.
- The Balloon Style preview matches the canvas. The Inspector's preview was a generic SVG sample whose shape, tail, and wrapping never matched the bubble on the canvas. For a selected bubble it is now drawn by the editor's own canvas renderer from the bubble's real geometry with the panel's live values, scaled to fit. The Balloon Style panel.
- Page-view autosave no longer wipes a panel's layers. Moving a bubble in panel view and switching to page view within the two-second autosave window could save an empty layer list and make the panel's artwork vanish. Entering page view now flushes the pending save first, and page-view saves leave stored layers untouched.
The player now plays the manifest's audio — and the toolbar toggles act on it
- Panel audio is played by the shell. A new
PanelAudioServicestarts everypanels.<id>.audio[]track andkind: "audio"layer when a panel becomes current and stops it on leave, honouringrole,loop,gain,startAtMsandvisibleIf. A looping ambience shared by consecutive panels keeps playing across them; tracks the browser refuses before the first gesture are retried on that gesture. Details: Audio. - Audio and SFX toggles are real. Audio is the master mute for
every bus and video sound (video layers follow the engine);
SFX mutes the
sfxbus (incl.uisounds); Speech additionally mutesvoiceover. Initial state: the reader's stored preference, else the work'ssettings.ui.audioDefault/sfxDefault/speechDefault. Each toggle emits itsaudio_toggle/sfx_toggle/speech_toggletracking event. Toolbar controls. - Settings modal preferences apply. Speech, audio, SFX, autoplay
and seconds-per-panel saved in the modal now take effect and
persist (
localStoragepw-preferences, only explicitly set keys);PlayerStateServicegainedpreferences$,updatePreference(s)andhasPersistedPreference. - Audio engine fixes: each track now has its own gain node, so
fades and per-track
gain(0–2) no longer touch a whole bus (the previous fade code ramped the first bus it found); mute flags (setMasterMuted,setRoleMuted) are independent of volumes; one-shot tracks release their element onended.
Declare your story's state in the CMS, not in a hand-edited manifest
Variables used to reach a work only by importing a manifest that already contained them. They now have their own Backstage page:
- The Variables designer is enabled. Open a work's Backstage and
choose Variables (the editor's work-areas menu has the same
entry) for a table of every definition — id, type, default, scope,
read-only/private flags, description — with a search box and
type/scope filters, and create / edit / duplicate / delete actions.
Ids may be dot-namespaced (
inventory.hasKey),enumvariables list their allowed values, and changing a type resets a stale default. Details: The Variables designer. - Validation on both sides. The dialog catches a malformed or duplicate id and a default that doesn't match its type, and the server re-checks the same rules — what you save always validates against the schema.
- JSON import and export. Export JSON downloads the
definitions as a manifest fragment
(
{ "variables": { "definitions": [ … ] } }); Import JSON accepts that fragment, a plain{ "definitions": [ … ] }, or a bare array, and replaces the current list after a confirmation. Import and export. - Published manifests carry valid variables. The manifest builder
emitted
variables.definitionsas an id-keyed map, which is not what the format specifies — it is now the array the schema requires, so players read the definitions as intended. - Import keeps your variables. Importing a manifest or a
work archive silently
dropped its
variablesblock; definitions now survive the round trip, with invalid entries skipped and logged.
Reader-side values are still simulated in Preview's variable overrides, which replace the old standalone simulation page.
Schema 1.5.0: works that round-trip between authoring systems
Format release 1.5.0 — additive as always, every existing manifest stays valid. Two new authoring metadata blocks let a complete work travel between authoring systems without losing organization or translation state (rendering consumers may ignore both):
assets.folders+ per-assetfolderIds— the asset library's folder tree (nested viaparentId, ordered, n:m assignment). See Assets.- Top-level
localization— the translation workflow state: locale list with default/active flags, and per-string entries withdefaultText, per-locale values, stale markers, and machine-translation flags. Reader-facing text stays inLocalizedStringobjects as before.
@panelwave/types and the CLI are synchronized
(validate + upgrade now target 1.5.0). These blocks are what the
CMS's new work archive transfer is
built on. Details: Versioning.
Move whole works between systems, and a structure tree that does what you drop
An afternoon of transfer and editor work in the CMS:
- Work archive export & import — a work can now travel as a single
self-contained
.ziparchive: the manifest for all page formats plus every asset file (originals and all generated variants — nothing is re-transcoded on the other side), asset folders, and translations. Export it from the works list like any other export format, import it on any other PanelWave system or account via Import Archive on My Works — dev to production, between accounts, or as a full local backup. Imports are atomic, arrive as drafts with fresh ids, respect your plan's limits, and can be retried from the dialog if something goes wrong. Publish history, paywall configuration, analytics, and community data intentionally stay behind. - Insert panels exactly where you want them — the Create New Panel dialog gains a Position select ("At the beginning" / "After panel…", defaulting to the end), and dragging a panel from Unassigned onto a page now inserts it at the drop position instead of always appending — with the canvas renumbering immediately rather than after a browser reload.
- Deleting a shared panel no longer breaks other formats — panels that appear on pages of several page formats are only detached from the page you delete them on; the other formats keep their copy. Creating panels from the tree also no longer corrupts existing page placements.
- Speech bubbles: move between panels, stay where lettered — a bubble's right-click menu can now move it to another panel directly on the canvas, freshly created bubbles no longer vanish from page view until reload, and boosted balloons stopped drifting off their tails.
- Video panels behave — a dropped video is recognized as the panel's background again (so the panel adopts its proportions), and the panel's duration syncs to the video's length on drop.
- Small but daily — timeline footer actions are reachable in the collapsed timeline bar; timeline resizes grab the right panel; the canvas context menu correctly enables Arrange / Duplicate / Delete for the selected panel; and API validation errors now show what failed ("Placement #6: x must be between 0 and 1") instead of a bare "Validation failed".
Page backgrounds that publish, page ids that make sense, edits that stick
An evening of page-properties and reliability work in the CMS editor:
- Page Properties, reworked — the dialog now looks and behaves
exactly like Panel Properties: shared sections with persisted
collapse state, and the page title and chapter resolve through the
current locale (titles previously showed empty for BCP-47 locales
like
en-US). The production Status is a compact row of four colored buttons instead of a radio list. - Page background colors that actually publish — the background
color picker works now: a curated preset palette for graphic-novel
pages (paper whites, grayscale steps, sand/cream tones, soft
pastels), custom colors by hex code, and a persisted Recent row.
The chosen color renders on the canvas immediately, and the
page's
visualblock now flows into published manifests — it was previously dropped, so page backgrounds never reached the player. Along the way: saving page properties no longer fails when a value is cleared, and saved properties no longer vanish on reload. - Format-scoped page ids — pages in the manifest used to share one
running counter across all page formats, so
the second format's pages started at
pg-41. Each format now gets its own letter and counter:pg-A1…pg-A17,pg-B1…pg-B13, … Existing works pick the new scheme up automatically. - Panel auto-fit in every format — when a panel receives its first image or video, its proportions now adjust to the artwork in all page formats the work supports, not just the one you are viewing. The panel keeps its top-left position and only ever shrinks, so it always stays on the page; panels that already contain media are never resized by later drops.
- Panel-view edits always show up — layers added or edited in panel view now appear in page view right away (previously new images could stay invisible until a browser reload), and edits made moments before switching panels are saved first instead of being lost or written to the wrong panel.
- Asset library loads everything — works with more than 50 assets showed only the newest 50 in the Assets tab (which also made deleting one asset look like it removed others). The full library now loads, folder counts refresh after a delete, and deleting an asset also removes all its generated variants (responsive sizes, thumbnails, posters, video renditions) from storage.
- A11y tab restyled — the accessibility inspector now matches the other inspector tabs and works in dark and high-contrast themes.
Organize faster, drop with confidence, edit video with bubbles in view
A day of asset-library and canvas work in the CMS:
- Multi-select in the asset library — Shift/Ctrl-click assets to build a selection, then drag any of them to file the whole selection into a folder (or onto Unfiled to clear their folders). A toolbar chip shows the selection count.
- Uploads land in the selected folder — with a folder active, the Upload button shows the target folder as a chip and new files are filed there automatically; folder counts refresh as uploads finish.
- Assets always know their size — image and video dimensions (and video duration) are measured in the browser at upload and stored immediately; older assets are measured on first use. Dropped media now always keeps its true aspect ratio: the first image or video in a panel becomes its background and the panel's proportions adjust to the media, so artwork never appears stretched. Freshly uploaded images also render in page view right away.
- Video posters everywhere — the poster frame now serves as the video's thumbnail in the asset library grid, the asset picker, and the details panel; videos uploaded before poster support get posters backfilled automatically.
- Speech bubbles stay on top of video — in the editor, bubbles, the play-mode badge, and selection handles now render above a video panel even during playback, so you can position dialogue against moving footage (see Video Panels).
- Details drawer upgrades — the asset details panel shows the asset's folders and live dimensions/duration (with a brief Measuring… state for older assets).
- Fixed: switching to a panel without artwork no longer keeps showing the previously edited panel's layers in the editor.
Script import: faster passes, finished works that feel finished
A round of quality and speed work on the Fountain script importer, based on real end-to-end imports:
- Much faster AI passes — the structure pass completes in about a minute, and page layouts for all output formats are now generated in parallel instead of one format at a time (a 4-format import that took ~20 minutes now takes a few).
- Real titles everywhere — panels are titled from their art brief and every page gets an AI-generated title describing its content; no more trees full of "Imported Panel" / "Imported Page".
- Bubbles arrive finished — speech bubbles are styled by kind through the balloon engine from the first render, are visible in page view, and have their speaker pre-assigned to the created character.
- Supported formats stick — the created work is restricted to the output formats chosen in the wizard, so editor format pickers only offer what you target.
- Structure review upgrades — bubbles can be moved to any panel via the inspector (including collapsed panels and other chapters), + Panel inserts after the current selection, and panel/bubble ids renumber to reading order after every edit.
- Big screen format clarified — it is a 4K (3840×2160, 16:9) format holding 4–12 panels per page; pickers and layout guidance now say so.
One panel, many stories — panel variants work end-to-end
The format's conditional-content feature is no longer just a schema entry: variants authored in the CMS now publish into the manifest and actually render in the player. The same panel can resolve a conflict by committee for one reader and at high noon for another — or soften its artwork for readers below an age threshold.
- Selection rule codified — variants are evaluated in manifest
order and the first one whose JSON Logic
whenmatches the current variables applies; overridden fields replace the base panel's values wholesale. Unknown or failing conditions count as false, so gated content fails closed. See Panel Variants. - Live in the player — variants re-resolve the moment a variable changes (hotspot choices, edge mutations, host calls), and can swap layers, speech bubbles, hotspots, titles, even the panel's autoplay duration. Readers get an Alt toolbar button on panels with variants to cycle alternatives manually, plus an on-screen chip showing the active variant. See State & Conditions.
- Trustworthy inputs for gating — a new
initialVariablesplayer input (and the entitlement adapter's context) seed variables at startup through a privileged path that may populatereadOnlydefinitions. Declareuser.ageread-only, seed it from your account system, and no in-story mutation or settings edit can ever change it. See Inputs & Outputs. - Reader-editable preferences — the settings modal's Variables tab is live: variables marked public (the default) and not read-only can be changed mid-read, with variants updating immediately — "EU style" vs. "US style" is one dropdown away.
- Authoring in the CMS — the panel inspector's variant editor now speaks the format natively: a visual JSON Logic condition builder over your defined variables, typed override editors for titles and durations, and copy-from-panel seeding for layer/bubble/hotspot overrides. Publish validation flags duplicate variant ids, missing conditions, and references to undefined variables, and variant texts flow through translation extraction and write-back like any other localizable string.
- Fixed along the way — published manifests previously dropped
variants silently, and dot-namespaced variable ids like
path.choicenever resolved in any JSON Logic condition (this also affected conditional edges andvisibleIf). Both work now.
Hotspots now actually work — and you can watch readers use them
- Interactive hotspots in the player — the hotspots you draw in the editor now render and act in the published work: readers see a gentle pulsing outline (respecting reduced motion), and activating a hotspot runs its action — navigate with variable changes and a transition, set variables, open extras at a specific item, open a modal with localized text, or trigger a plugin event. Fully keyboard-accessible with localized screen-reader labels, in panel and page view. See the reader's view.
- Click heatmap in the analytics dashboard — a new section shows where readers click on each panel as a cool-to-hot density overlay, with hotspot outlines, per-hotspot hit counts, and the dead-click share: taps that hit no hotspot, i.e. places readers expect interactivity. Reads raw clicks, so it updates without waiting for the nightly aggregation. See Click heatmap.
- Reading funnel & panel engagement documented — the dashboard's per-panel drop-off funnel and views/dwell/bounce table now have reference docs.
- Editor fix — hotspots are reloaded when you reopen a panel (they previously disappeared from the canvas after a reload while still being saved), and hotspot geometry is stored in the format's normalized coordinates so exports are always schema-valid.
- Tracking — the player records
hotspot_clickevents with normalized coordinates and a hit/miss flag, consent-gated and whitelisted like every other event. See Tracking.
Talk about the work where the work is
- Team comments are live in the CMS — a Comments section in backstage holds the work-level discussion, and a speech-bubble button in the editor header opens a comments drawer that targets the most specific thing you have open: the selected panel, otherwise the current page, otherwise the whole work. Threaded replies, six emoji reactions, edit/delete of your own comments, and Newest/Popular/Oldest sorting. Comments are team-internal: only members of the work's team can read or post. See Community.
- Moderation & abuse protection — every comment route now requires membership of the work that owns the target. Authors with a verified email post immediately, others are held for review; spam-shaped content (too many links, blocklisted terms) is held rather than rejected, and rapid-fire posting is rate-limited.
- High-contrast theme — a third theme joins Light and Dark, selectable in Profile → Preferences and cycled from the editor's user menu, with a full token set in both the app and the editor canvas.
- Accessibility polish — progress bars, tab strips, and tooltips across
the app moved onto shared, ARIA-correct components: real tablists with
arrow-key navigation in the Extras manager, tooltips instead of bare
titleattributes in the works list, and progress values clamped against misreporting backends.
The placeholder mark retires
- The CMS shows the PanelWave brand icon in the editor and backstage headers and ships a complete favicon/app-icon set — browser tab, bookmarks, apple-touch-icon, and a web manifest for installs.
- The website renders the icon next to the wordmark in header and footer, replaces the placeholder favicon set, and the press page's Media Assets now offer the real icon and full logo lockup for download.
- The auth screens greet you with the brand mark instead of a generic icon.
Pick your page formats — per work, from creation to export
- Page Formats step in the create-work wizard — choose every screen or
print shape the work targets (all eleven formats of the schema's
OutputFormatenum, from Mobile portrait to US Letter and Video 16:9) and badge one as the default for previews and exports. Starter templates pre-select fitting formats. With "Start with a first chapter" ticked, the wizard now seeds an empty Page 1 in every selected format, so the editor is never empty. See Works. - Supported-formats editor in Work Properties → Output — add formats later (with an optional empty first page per chapter; chapters that already have pages in that format are skipped) or remove them again. Removing a format that still has pages warns first and keeps the pages — they reappear when the format is re-added. The default format cannot be removed. See Works.
- The editor honors the list — the canvas format switcher offers only the work's supported formats, and a remembered selection that is no longer supported falls back to the default format. Works from before this feature keep seeing all formats until they save an explicit selection. The switcher also gained the missing frames: US Letter portrait/landscape, Video 16:9, and Flex landscape.
panelwave.org is live
- The hosted CMS is live in a gated private beta on panelwave.org, with automated deployments. Public work URLs (the slug preview in the create-work wizard) now show the panelwave.org domain.
- Export fixes — PDF, PPT, and video exports handle partially specified options again (generators fill sensible defaults), and the export data pipeline was aligned with the current manifest schema. See Export.
- Smarter AI import — the script and page importers upgraded to a stronger reasoning model for panel, layout, and bubble suggestions.
Right-sized artwork everywhere — and GDPR self-service
- Responsive image variants (CMS) — the media pipeline now renders every image into a WebP size ladder (640 / 1280 / 1920 / 2560 px wide; only sizes below the original are created). Published manifests list the rungs as ascending variants while the full-quality primary file stays first, so older players keep working unchanged; a backfill job brings existing libraries up to date. The editor itself also loads size-matched renditions in asset lists, the picker, and on the canvas. See Assets.
- Variant-by-zoom in the player — panel and page view now pick the image
variant by actual display size (container width × zoom ×
devicePixelRatio, quantized, upgrade-only — no flicker back to
thumbnails), completing the selection machinery canvas view shipped with
format 1.4. Panel view additionally preloads the next panels along
outgoing graph edges at the size they will render at, honoring
settings.preload. See Performance. - Delete your account yourself — the profile's Danger Zone gains a permanent Delete account action with typed confirmation: immediate deactivation and sign-out everywhere, then anonymization after a 30-day grace period (support can cancel within the window). Works of teams where you were the only member go to the trash. See Account & Team.
- Automatic data retention — background housekeeping now deletes raw analytics events after 24 months (aggregated dashboard metrics are kept) and expired/revoked sessions after 90 days.
The infinite canvas: one continuous plane, a camera on the trail
Format 1.4.0 brings the infinite canvas to the whole PanelWave stack: a chapter's panels can live on one continuous world-space plane, and the reader's screen becomes a camera that glides between them along the story graph. A single-column layout is a webtoon-style vertical strip; free 2D placement with camera trails is the full experience. All additive — works without a canvas are untouched, and print keeps using pages. See The Infinite Canvas.
Format (schema 1.4.0) — all additive; see Infinite Canvas:
Chapter.canvas— world-unit panelplacements(1 wu = 1 CSS px at zoom 1; rotation, stacking, panel-relativeenterFraming),revealModespoiler protection (always/on-approach/on-visit), planebackground, camera policy (fitMode,overview,freeRoam,bounds), and presentationaldecorationswith parallax depth.Edge.cameraMove— camera travel per graph edge:direct/arc/waypointspaths,hold/pull-back/divezoom profiles, duration, easing, and areducedMotionFallbacktransition. Inherits liketransitionvia the newFormatPreset.defaultCameraMove.FormatPreset.canvasView— per-format opt-in; players without it (or without canvas support) fall back to panel view.@panelwave/clivalidates the new semantic rules (placement keys must be chapter panels, performance budget, waypoint consistency) and itsupgradetarget is now synchronized at1.4.0.
Player — a third view mode alongside panel and page view; see Canvas View:
- Camera glides with authored paths and zoom profiles (motion-safety speed
cap, interruptible by the reader), overview zoom (
O), guided or free-roam input on touch, mouse, and keyboard. - Virtualized rendering (≤ 12 mounted panels regardless of chapter size),
variant-by-zoom image selection (overview mounts thumbnails,
close-ups load full resolution, upgrade-only — no flicker), and
settle-time neighbor preloading honoring
settings.preload. - Accessibility built in: no gliding under reduced motion (cross-fade
reframes instead), full keyboard traversal,
aria-hidden/inerton non-current panels, graph-driven reading order. - New embedding API:
viewModeOverrideinput and throttledcameraChangeoutput.
CMS — a new authoring surface; see Canvas Layout Board:
- Spatial board with live panel artwork, graph-edge arrows, drag/resize with snap, align/distribute, and auto-layout presets (vertical strip for webtoon-shaped works, layered graph layouts for branching 2D canvases).
- Camera-move inspector with path ghosting and draggable waypoints, gap calipers showing distance-as-time in beats, an enter-framing tool, per-panel reveal modes, and decoration authoring (opacity, parallax, rotation).
- Work Properties → Output gains per-format Infinite Canvas View toggles; publish preflight validates canvas integrity; the Preview tab's new View selector compares panel and canvas modes on the live manifest.
Import finished pages, upscale panels, and publish for real
- Page Import (AI panel splitting) — a new importer for artists who already have finished works as flat page images. Upload PNG/JPEG/WebP pages, AI detects the panels (regular grids, full-bleed artwork, and nested inset panels) with a selectable EU/US or manga reading direction, and a review step lets you move/resize/add/delete panels and fix the reading order before anything is created. On import every panel is cropped borderless from the full-resolution page, saved as an asset, and placed at its original position on a PanelWave page — with a linear reading graph so the work is playable immediately. See Page Import.
- AI upscaling with credits — optionally enlarge small panel crops for sharp desktop/4K display (Standard 1440 / High 2560 / Ultra 3840 px targets). Upscaling is billed in credits, PanelWave's new prepaid wallet for metered AI features: plans include a monthly allowance, the wizard shows the exact cost against your balance before you commit, and panels that fail to upscale import at original resolution with their reserved credits returned automatically.
- The publish pipeline is live — the guided Publish flow (preflight → environment → options → confirm) now runs end-to-end, and a Preview publish mints an unguessable, revocable preview manifest link that any PanelWave Player can load without a CMS login — ideal for sharing a work-in-progress with testers. See Publishing.
- Size & Content stats — the publish result and the Work Properties Metadata tab now break a work's weight down into manifest size, asset count and payload, and the total.
- Player demo: external manifests — the demo app accepts
?manifest=<url>, so a CMS preview link opens directly in the standalone player. See Contributing.
Organize the library, pick assets anywhere, and upload straight into Extras
- Asset folders — the Assets tab gains a folder pane (nested folders, drag-to-file, per-folder counts, an Unfiled view). Folders are purely organizational and never affect exports.
- One asset picker everywhere — a new Browse library… dialog with the folder tree on the left, the searchable/filterable library in the center, and a large preview with details on the right. It opens pre-filtered to the type a field expects, and an in-dialog Upload drops new files into the selected folder and picks them immediately.
- Extras take library assets — an extra's content and thumbnail can now be picked from the library or uploaded on the spot, in addition to external URLs. Linked assets appear as a chip (change / clear), auto-fill dimensions, duration, and file size, and stay connected — Replace File on the asset updates the extra automatically.
- Characters too — portrait and reference images gain a From library button next to upload and URL paste. Page background images/textures and video layers use the same picker.
- Fix: images no longer expire — character portraits and extras previously stored short-lived signed links that broke ~24 hours after saving. Stored links are now durable and re-signed on every read, and published manifests always carry fresh asset URLs.
Details: Assets, Extras, Characters.
Optimize oversized images from preflight, and a faster path between work areas
- Optimize / Optimize all — oversized-image errors (over the 5 MB publish limit) now carry an Optimize button in preflight and in the publish wizard. The CMS re-encodes the image as WebP in the background (stepping down quality, then resolution, until it fits), keeps your full-quality original in the library, and ships the optimized variant. The issue list polls until the queued jobs finish and the errors clear on their own; Undo restores the previous state.
- Fair size check — the oversized check now judges the effective shipped size, so an already-optimized image isn't flagged again.
- Work-areas menu — a grid-icon dropdown in the editor header jumps straight to Characters, Extras, the Graph Editor, Paywall & Entitlement, Localization, Audio, and Analytics.
- Fixes — publishing no longer fails with a 404 on the validation call; the works list shows creators again; failed optimize jobs can be retried immediately instead of silently doing nothing.
Details: Validation, Publishing, Editor Layout.
Video panels play in the editor, and better timeline transport
- In-editor video playback — a video panel now plays right on the editing canvas. Hover it for a play / pause / stop toolbar, and in Panel View the footage fills the canvas so you can check framing. Clicks outside the toolbar still select and drag the panel as before.
- Timeline drives the video — when you run the timeline, each video panel plays automatically while the playhead is inside its time range, seeking to match the playhead and pausing when it leaves. Scrubbing while paused shows the matching frame, so the timeline preview mirrors reader autoplay.
- Jump-to-start / jump-to-end buttons — the single-arrow buttons step one
frame (so at the end they barely move); new ⏮ / ⏭ buttons snap the
playhead to the first or last panel and switch the canvas to it, matching the
Home/Endkeys. - No more autoplay "Loading…" flash — panel images are preloaded, so switching panels during autoplay no longer flashes a grey placeholder while each image decodes.
- Fixes — video posters now resolve reliably on the canvas (asset-id matching and asset-list variants), and the Preview tab loads its manifest on a direct visit instead of showing "No Manifest Available".
Details: Video Panels, Animations & Timeline.
Narrator caption boxes & format-independent speech bubbles
- New
narratorballoon type — a true sharp-cornered rectangle for narration caption boxes (unlikerectangle, which keeps a subtle corner rounding). Additive enum extension across schema,@panelwave/types, the player's ComicBalloon renderer (newsharpCornersflag), and the CMS. - Panel-relative bubble geometry — the CMS now stores a bubble's
shapebox exactly as the format defines it: normalized against the panel artwork, not the editing canvas. Bubbles keep their position on every device format, and Panel-Top / narrator caption boxes stay glued to the panel border everywhere — panel view, page view, and player. - Per-format lettering size — balloon text keeps the same comfortable reading size on each target screen: unchanged in A4-sized formats, moderately larger on big screens, smaller on phones — never proportional to the artwork. Page view renders balloons text-fitted, with a readability boost capped at 75% of the panel.
- Player: per-screen lettering — the open-source player applies the same
rule at playback time. Balloons render at their measured, text-fitting
size scaled by the player viewport (DIN A4 height = 1.0); the stored
shapebox is a position anchor with border-flush edges glued, no longer a display size. Lettering stays comfortably readable on every device instead of blowing up on big screens. - Editor quality of life — the Add Speech Bubble context menu offers all ten balloon types including snap-to-border Narrator/Panel-Top placements; the panel border is magnetic when dragging caption boxes; speech bubbles resize via their corner handles; the canvas backing store is HiDPI-aware (crisp lettering on scaled displays); and the editor restores your last page/panel view after a browser reload.
Details: Speech Bubbles (format), Speech Bubbles (editor), Balloon Renderer, Canvas.
Format 1.3 — reusable style presets & implicit speech toggle
Additive, backward-compatible release: every valid 1.0–1.2 manifest remains valid unchanged.
- Reusable style presets — like CSS classes for the manifest. Named text
styles in
settings.typography.textStyles(referenced byTextLayer.styleRef) and named balloon presets insettings.typography.balloonPresets(referenced bySpeechBubble.styleRef). Shared styling is defined once and edited in one place; the balloon cascade becomes work → character → preset → bubble. Sample 11 replaced 104 identical caption style blocks and 79 repeated balloon overrides with one text style and six balloon presets. - The speech toggle is implicit — every speech bubble is inherently
subject to the reader's speech toggle (initial state:
settings.ui.speechDefault). The per-bubblevisibleIf: {"var": "prefs.speech"}boilerplate is obsolete;visibleIfis reserved for story logic, and a forgotten boilerplate line can no longer make a bubble immune to the toggle. - Player — text layers and balloons resolve
styleRefpresets; the toolbar speech toggle is functional and seeded fromspeechDefault. - CMS — presets are exported with the manifest,
styleRefround-trips through the editor, validation warns about dangling preset references, and legacyprefs.speechboilerplate is stripped on export.
Details: Settings, Speech Bubbles, Layers, Versioning.
Format 1.2 — leaner manifests
Relaxing, backward-compatible release:
mimeoptional on image/audio/video/subtitle/vector variants — consumers derive the MIME type from thesrcfile extension.- Edge transition inheritance — edges without a
transitioninherit the active format'ssettings.outputPresets[format].defaultTransition. - Export discipline — exporters omit values equal to schema defaults.
Details: Versioning.
CMS — AI-assisted script import (Fountain)
Turn a screenplay in the open Fountain format into a PanelWave work — reviewed by you at every step:
- Upload & parse — scenes, dialogue, and cast are extracted with exact source-line provenance; a parse summary shows what was found.
- AI structure suggestion — chapters, panels with art briefs, and typed speech bubbles (speech, thought, shout, whisper, caption, narration, SFX). Dialogue is guaranteed verbatim: rewritten or dropped lines are detected and restored automatically.
- Structure review — a three-pane tree editor with drag & drop, panel split/merge, cast merging, a source-line drawer, undo/redo, and autosave.
- AI page layouts — pages laid out per output format (mobile, desktop, print, square, video …), refined in a drag & drop preview.
- Work creation — a schema-valid manifest is built and imported atomically; speech bubbles come prepositioned, artwork is added behind them in the editor afterwards.
- Plan-tier metering — script imports are allowance-gated per subscription tier, with per-session retry caps.
- Resilient by design: if the AI service is unavailable, a deterministic fallback still produces an editable suggestion.
Details: Script Import (Fountain).
Documentation site — initial release
First public release of the PanelWave documentation, covering:
- Documentation — introduction, quickstart, and core concepts
- Schema — full format reference for every manifest section, plus validation and the CLI
- Player — embedding, configuration, and architecture of
@panelwave/player - CMS — creator guides for the editor, assets, localization, publishing, and monetization
- Help Center — FAQs, troubleshooting, and guides
Format 1.1 — video panels
Additive, backward-compatible release: every valid 1.0 manifest remains valid unchanged.
- Video playback control on video layers:
playMode(once,loop,pingpong,loop-from),startMode(on-view,on-hover,on-click),loopFromMs, and nativecontrols. - Work-level video defaults in
settings.ui(videoPlayModeDefault,videoStartModeDefault,videoMutedDefault), cascading to per-layer overrides. - Video variants can mark a playback
direction(forward/reverse) for pre-rendered reverse encodes used by smooth ping-pong playback. - Poster frames on video catalog items for click-to-play and reduced-motion presentation.
- Tracking event whitelist extended with video playback events.
- The 1.0 fields
autoplay/loopon video layers remain valid; the new fields take precedence when both are present.
Details: Video schema reference and Versioning.
Format 1.0 — initial public specification
First public release of the PanelWave manifest format (JSON Schema 2020-12, CC BY 4.0):
- Chapters, pages, and panels with layered content (image, video, text, audio, plugin layers)
- Graph-based flow: entry panels, edges, transitions, and JSON Logic conditions
- Asset catalog with image/audio/video/subtitle variants
- Typed variable system with five scopes
- Localization via
LocalizedString, BCP-47 locales, and per-locale asset variants - Output format presets for web, print, and video
- Paywall and entitlement rules, tracking configuration, plugin support, accessibility hints
x-extension fields throughout
Details: Schema overview.