Skip to content

Release 1.26.0 — Edit many at once: prefabs that update, material presets and a new Settings - #341

Merged
AlexZ005 merged 78 commits into
mainfrom
feat/1.26
Oct 7, 2026
Merged

AlexZ005 merged 78 commits into
mainfrom
feat/1.26

Conversation

@AlexZ005

@AlexZ005 AlexZ005 commented Oct 7, 2026

Copy link
Copy Markdown
Collaborator

1.26.0 — Edit many at once: prefabs that update, material presets and a new Settings 🧰

Roadmap 37, release 1.26 (integrator 37-int-126). Lane PRs merged into feat/1.26 (merge commits, in this order):
#326 multiselect (R1) · #322 prefabs (R4) · #325 materials (R5) · #332 editor-small (R14 R15 R16 R18 R20 R25) · #321 slipped (21-C Race touch+VR, B4, C9 Race terrain) · #324 avatar-fix (R22 R23 R24) · #335 settings (R21, last).

Union fixes: peerHandler handshake union (wb: 1 + getchat); R14 Workspace layouts + R22 Knocked-off idle moved into the redesigned Interface page; R25 Undo on About ▸ Danger zone ▸ Reset all settings (asks first, then Undo); no toolbar Pivot cell under 440 px (the default bar was 402 px on a 393 px phone); layout-name field 16 px on phones; suites updated for R24 (flying opt-in), R1's DragRow fix (Esc after typing restores) and Svelte outro inert toasts.

Proof: svelte-check 306/47 (baseline 318 → 306), vitest 144 files / 1716, build, check:storage + check:tokens 0, ~100-suite e2e battery (reds A/B'd identical on 1.25.0 or fixed), perf budget GREEN (draw calls / tris identical to 1.25.0 for every game, desktop + VR), preview https://preview-1-26.theprototype.pages.dev proof ALL PASS. Modules: untangle 2.4.2 (modules #43 → main #45). Cloud #48 (report-a-problem) ships with this release.

🤖 Generated with Claude Code

AlexZ005 and others added 30 commits October 6, 2026 00:32
…con-through-Icon.svelte note (38-tokens R0)

- the CLAUDE-snippet from the redesign handoff, path adjusted to the cloud checkout
  (../cloud/docs/design/redesign/)
- icons note: SPEC 7 routes every icon (static ones too) through ui/Icon.svelte, sizes
  16/20; direct @lucide/svelte imports are legacy until R10

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…theme.json mapping, light values, check:tokens (38-tokens R2)

- src/styles/tokens.css: bg-app / surface-1/2/inset / border(-strong/-input) / text(-2/-muted/
  -faint) / accent(-soft/-muted/-text) / live / warn-text / danger / badge + control metrics,
  4px spacing, rem type scale (mobile < 640px: 16/14/16, 44px targets, 51x31 toggles)
- the five names the legacy themes already own (--text --text-2 --border --accent --surface-2)
  carry SPEC values only inside .tp-ui: dark leaves them undefined and ~400 call sites render
  their per-site fallbacks, so the default theme is unchanged
- light: its own block; green / 8-bit / contrast / custom .theme.json DERIVE every token from
  the legacy keys they already carry; old dark exports get the dark values
- app.css: @theme inline colour + type utilities (bg-surface-2, text-text-muted, text-body …),
  @theme static radii + font-ui / font-ui-mono (IBM Plex, self-hosted, OFL)
- themes.js: REDESIGN_TOKENS in THEME_TOKENS; export leaves DERIVED tokens derived
- scripts/check-tokens.cjs (npm run check:tokens, CI warning step): hex / rgb / Tailwind
  palette in src/components, --strict for R11, a CLEAN list that fails even now; unit test

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…(38-tokens R3)

- SPEC 2 primitives, every root in the .tp-ui token scope: WindowChrome (modal / panel / tool,
  mobile nav bar, footer; chrome only - open/pin/dock stay the caller's), Tabs (tablist,
  automatic activation, panel wiring), Segmented (radiogroup, one tab stop), Chips (single /
  multi), Toggle (aria-pressed, 40x24 / 51x31), Button (primary on --accent-fill = #2f6fe0,
  secondary, outline, ghost, warn-text, danger, icon + count/dot, live), Badge (scope / status
  dot / count / live), SettingRow (keeps .setting-row + .sr-name for Settings search; wide /
  stack), PropRow (wraps DragRow UNCHANGED: props + events pass through, restyled via the vars
  DragRow reads), NavRow, EmptyState, Sheet (peek / half / full, flick, drag to dismiss)
- Section grows variant=card (Settings; off the Inspector filter + deep links) and
  variant=panel (collapsible chevron); the default legacy markup is byte-identical
- from the design review page's kit: Menu, Toast, Checkbox (list pick only), SearchField,
  Slider; tokens --segment-on --axis-x/y/z --on-live --shadow-thumb; light values = the page's
- $lib/ui/roving.js + $lib/ui/sheetSnap.js (pure) with unit tests; Icon map + 13 names
- routes/kit: dev or VITE_UI_KIT=1 builds only (the import is dropped otherwise); every
  primitive in every state, ?theme=dark|light|custom|green|bit8|contrast, live token readout
  and a contrast table (all pairs >= 4.5:1 in dark, light, custom)
- e2e ui-kit (51 checks): tokens per theme, Toggle, Segmented, Tabs, Chips, Sheet detents /
  flick / dismiss, PropRow -> DragRow scrub / Shift / type / arrows / Esc; check:tokens CLEAN
  list covers every new primitive; svelte-check unchanged (318 / 47)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…oadcast (37 R5 phase 1)

- materialPresetsCore.js (pure leaf): payload v1 with one normalize at every boundary
  (IndexedDB, a peer, an imported file), the seven starters (wood, metal, plastic,
  glass, stone, rubber, neon) tuned for a scene with no IBL and the Quest budget
  (glass is clear-coat + opacity, no transmission pass), sameLook for the active
  swatch, uniqueName, capLibrary, swatchBackground
- materialPresetMaps.js: tileable procedural wood/stone height fields -> a luminance
  colour map + a tangent normal map, generated per device, never stored
- materialPresets.js: the library in IndexedDB (matpreset:<name>) with save /
  rename / delete / import / export, the per-person library broadcast on the
  envpresets shape (matpresets, mesh-wide, wireValidate row, handshake push, dropped
  at all three disconnect sites), and APPLY through UV4's objectParameters/materials
  payload: one undo entry + one message per object, D2 sharers handed the new instance
- fix: serializeMaterials handed ObjectLoader uuid-KEYED texture/image caches where it
  walks arrays by length, so every map on the materials path (slot commits, their
  undo, and undoing a preset over a textured object) came back untextured
- storage modal: a Material presets category with its own deleter
- vitest materialPresets (30)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ge (37 R4 phase 1)

- src/lib/prefabSync.js, a leaf (three only): an instance root carries
  userData.prefab {id, rev}; every node it got from the prefab carries
  userData.prefabKeys[id] = its stable key (userData.prefabKey on the
  library element, the node uuid the first time it was saved). Keyed BY
  PREFAB so an instance nested in another prefab keeps both links.
- mergeInstance(inst, base, next): an override is any field that differs
  from the revision the instance was placed from (top-level node fields,
  each userData key, the transform, geometry and material by CONTENT);
  overrides are kept, the rest comes from the new element. The root's
  position/rotation/name are the placement and always stay. Matched nodes
  keep their uuids (flow graphs, clips, physics survive), new prefab nodes
  are added, removed ones dropped (the user's children under them rescued),
  user-deleted ones stay deleted, user-added subtrees kept; `reset` takes
  the prefab everywhere but the placement.
- an overridden material whose uuid the prefab still uses elsewhere is
  re-minted (a parse keeps resource uuids, so an in-place edit collides).
- vitest prefabSync (20): keys, merge cases, nesting, unlink, overridesOf,
  and two counterfactuals (no keys -> the update reaches nothing; the
  re-mint guard goes red without it).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ser gate)

- docs/settings-inventory.md: every Settings category, section, setting and submenu as of 1.25.0
  (label, control, scope, store -> storage key) with the planned new section, label and control,
  the grouped navigation, the footer / Danger zone moves, every sub-page, the per-category reset
  key lists and decisions A-H
- docs/settings-storage-keys.md: the full key map (defaults, encodings, write timing, file:line),
  the oracle for the storage-key test
- docs/ is gitignored, force-added on request (the spec names this path)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…or mixed v2

- wireBatch.js (zero-import leaf): while a batch is open, broadcast holds room-scoped
  payloads and the outermost close sends ONE {type:'batch', items} envelope (a batch
  of one stays the bare message; a non-batchable send flushes first so order holds;
  chunks of 500). Receivers re-run every item through the whole dispatch chain
  (shape table, canApply, room + share-or-stash gates); envelopes never nest.
  Peers advertise wb:1 in the modules handshake; others get the items one by one.
- Producers: Inspector fanOn / colour drag / textures, multi-gizmo drag (live +
  final), panel pivot edits, undo/redo replays, group / ungroup / multi-delete.
- Inspector: mixed state (dash / indeterminate) on visible, cast/receive shadow,
  culling, click-through, render order, wireframe, flat shading, side, material
  type, colour + emission notes, physics body/material/collider/sensor/freeze;
  ThemedSelect gains a mixed prop. Object flags are undoable now (multiEdit.js
  'flags' kind) and Light rows fan over every selected light with a gesture-sealed
  'light' undo kind. Freeze toggles keep each member's other axes.
- vitest: wireBatch.test.js (10).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ed phase 1)

- touch 'drive' preset (stick steers, no look drag) + gas/brake glyphs; Race declares
  Gas/Brake/Reset while you hold a car; api.input() gains a `touch` stick channel
- api.vrSeat/vrUnseat (src/lib/vr/seat.js + pure seatMath.js): the XR space is carried
  rigidly with the object (yaw + translation), sticks claimed, step-out on unseat
- Race: VR engages in Interact (a headset never takes the pointer lock, so Race never
  engaged in VR before), seat swaps with the chase camera mid-race, pad/touch/VR sticks drive
- vitest vrSeat (6, counterfactual: flipped turn sign = 2 red) + drive preset; lifecycle
  fixture for vrSeat; e2e race-touch-vr written (first run queued, result not yet read)
- svelte-check 318/47 = baseline

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…2e pending)

- MaterialPresetsRow.svelte (own file, one Inspector line): apply via fanMat (one undo for N),
  save current, edit mode rename/export/delete (confirm), import, peer libraries + save a copy
- swatchLayers in the core; theme tokens only
- e2e material-presets written; NOT yet run green (queued on an e2e slot)
- svelte-check 318/47 = baseline

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- uiLayoutsCore (leaf, vitest): which stored keys are the layout, record
  normalize/upsert/rename/remove, the onLayoutRestore re-read registry
- uiLayouts: capture (open panels + layout keys), apply in four steps
  (close all -> write keys -> owners re-read -> reopen), no page reload
- re-read hooks: dragWindow, docking, bottomDock, windowTabs, the nine
  dock-family panels, the object list
- UI: menu > Layouts popover + Settings > Interface row (one component)
- svelte-check 318/47 = v1.25.0 base; e2e suite workspace-layouts OWED

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…nces" (37 R4 phase 2)

- prefabs.js: every element write is keyed (stampElementKeys); updatePrefab /
  restorePrefabBytes keep the old bytes as a REVISION (idb prefab-revs-v1:<id>,
  newest 8) and bump `rev`; instantiatePrefab links the instance (root
  userData.prefab {id, rev}, per-node prefabKeys) for library prefabs only;
  a prefab carries its objects' flow graphs (`graphs`, keyed by element node,
  the .tpnode payload shape) and installs them on placement; toJSON after
  updateMatrixWorld.
- prefabLinks.js (new): prefabInstances, prefabInstanceCounts, updateInstances
  (merge per instance against the revision it was placed from, replace IN
  PLACE through the existing `object` override message, graphs replaced via
  nodedelete/edgedelete + graphcreate/nodes, ONE `prefabsync` history entry),
  offerInstanceUpdate (toast: Update N instances / Update, reset overrides /
  Undo), applyInstanceToPrefab, resetInstance, syncInstance, unlinkInstance,
  selectInstances, instanceOverrides.
- Explorer: Update from selection offers the instance update; card menu
  "Instances in scene (N)". Object menu: "Prefab: <name>" submenu (Update
  from prefab / Apply changes / Reset overrides / Select all / Unlink).
- saveAs snapshot path keys + captures graphs; Icon gains tag/unlink/upload;
  debugHooks rows prefabLinks + prefabSync.
- svelte-check 318/47 (baseline), vitest 1564 green. e2e NOT yet run.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… keys claim

- Race claims 'keys' (it reads input itself), and TouchPlayControls stood the whole stick
  down under any keys claim, so a phone could not steer (race-touch-vr run 1: move.x 0)
- resolveTouchControls reports declared; the stick (not the look drag) stays live when a
  module declared the controls; vitest touchActions 27/27

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…-read, UI, reload, Settings)

Written, not yet run green - queued on the snapshot runner.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… object list

- dragUuidsFor: a row that is part of a multi-selection drags every top-level member
  (application/x-object-uuids JSON beside the old single key, which older drops read)
- moveObjectsToParent(uuids, target): a group takes them in, ANY other object becomes
  their parent (moveObjectToGroup gains {anyParent}; receivers' createGroup already
  attaches to any uuid), 'root' from the list body/header. Cycles and non-editable
  members are skipped; ONE undo step and ONE replicated batch for the set.
- local-only members dropped onto a shared parent are shared into it, as before.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…tab (37 R4 phase 4)

- prefabLibraryCore.js (pure, vitest 10): tag/folder normalisation, the view
  (folder cards + the prefabs filed here; a search or tag filter reaches every
  prefab below the folder, tags AND, search matches name or tag), free folder
  names, rebase for rename/move.
- prefabLibrary.js: prefabFolder / prefabTagFilter / prefabFolderList stores,
  folders persisted in idb (an empty folder is a place), create / rename /
  delete (contents move up, nothing deleted) / move, set and add tags. LOCAL.
- prefabs.js patchPrefabs: one write path for folder/tag edits.
- Explorer: folder cards (prefab-folder), breadcrumb Prefabs / A / B, New
  folder on the grid background (inline card), card menu Move to folder +
  Edit tags, folder card menu Open / Rename (inline) / Delete folder, a prefab
  dropped on a folder card is filed there, PrefabTagBar under the crumbs.
- PrefabDetails in the prefab's Properties: folder, tags editor, copies in the
  scene (Update all / Select), carried logic + Export .tpnode.
- e2e suites written: prefab-propagation (two peers), prefab-library.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ies the whole selection

- Toolbar: a default Pivot cell after Scale (glyph + title name the mode; a click
  steps Median -> Active -> Individual (-> Parent when the set shares one)). The 33 E1
  shipped row migrates; custom bars get it appended (the existing new-button rule).
  controls-roster / editor-ui-33 expectations follow the new default row.
- VR: a 'Pivot point' choice row on the Editing page of the ONE settings schema
  (radial Settings ring, headset panel, desktop Settings > VR), bound to the same
  pivotMode store; crosshair glyph added to the headset icon table.
- VR set grab (vr/setGrab.js pure maths + grip.js): an Edit grip on a member of a
  selection of 2+ no longer collapses it - the hand's translation moves every member,
  a wrist twist turns and the stick's X scales the set about Median / Active / Parent /
  each own origin. Moves stream as ONE replicated batch (own 50 ms throttle - the
  single-object throttle is global); release = ONE transformSet undo. Every existing
  release site ends it through endGrab. vitest setGrab.test.js (6).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A save/rename/delete is several IndexedDB round trips; at load ~125 the fixed 700-800 ms
sleeps read the row before the write landed (a single-page probe showed the row updating
correctly: one module instance, the swatch present). Poll the swatch / library instead.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…layMode/inGame (36 B4 remainder, DEVX #29/#31/#11)

- src/lib/modulePointer.js: a module press-drag-release seam; down() returning true OWNS the
  gesture (Scene: Edit/Interact, orbit stands down; playInteract: Play, no carry/tap)
- src/lib/sdk/pointerSeam.js: one new slice + one SDK_TABLE row; every registration journalled
  (lifecycle fixtures registerPointerHandler/onClickMiss/onPlayMode run in node)
- race-touch-vr: VR sections 5-6 moved to a fresh page that never pressed desktop Play
- gates: vitest lifecycle/touch/seat/debugHooks green; svelte-check 318/47 = baseline
- e2e module-pointer-seam run 1: 15 PASS / 3 FAIL — the Play hook offered presses outside
  Play (FIXED here, gated on isLocked, not re-run); the Edit sky click never reached
  onClickMiss (OPEN); race-touch-vr run 3 died on the suite's kit call (OPEN)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Mixed dash/indeterminate, one batch + one undo replicated to a second peer, each pivot
mode via the Inspector rows, the toolbar Pivot cell, drag a selection onto a group and
onto a mesh (parenting), cycle refusal. First run: 27 PASS / 15 FAIL, all traced to the
suite (only one member changed in 2.1/2.5 - a bare message is correct; the 1.3 probe read
the label not the field; 3.x cascaded from an Enter after a live-applied rotation) -
fixed here, re-run owed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…orer follows the folder menu

- prefabLinks: the merged ROOT carries no prefabKeys entry (it is the link), so
  the graph walk never matched a flow graph on the root object — the case of a
  one-object prefab. The root now matches by the element root's key.
  (prefab-propagation read "copy 2's graph took the prefab's second node (1)".)
- prefab-explorer: the Prefabs background now offers a prefab "New folder"
  (37 R4); the check asserts it and keeps refusing the scene/project entries.

Battery before this fix (lane 5352): prefab-library 18/0, prefabs 20/0,
vr-prefabs 14/0, music-prefabs 14/0, prefab-propagation 23/3 (the graph
checks), prefab-explorer 103/2 (this contract). Re-run owed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…aking, --live stays Play/record/stream

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…the list drag through the rows' real handlers, probe type+Enter on the pivot rows

Run 2 (previous commit): every Inspector / batch / undo / pivot-mode check PASSES; the
remaining reds were the premise read before the modules handshake landed and Playwright's
dragTo timing out on the tabbed object list (now synthetic DragEvents with one shared
DataTransfer through the rows' own dragstart/dragover/drop).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Section 5 reloads A, which makes it a NEW peer; section 7 dialled the stale id and waited
for an Approve card that could never come (run 2: 29 PASS, then connect died).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… slope/height look (21-C C9, not yet authored)

- race-touch-vr run 4: 38 PASS 0 FAIL (phone pedals + steering, VR seat, VR Interact with no lock, step-out)
- module-pointer-seam run 2: 18 PASS, 1 FAIL that was the assertion (moves stayed 16 -> 16 on the
  unclaimed drag); the check now compares to the count before that drag (not re-run)
- scripts/templates/race.cjs: RACE_TERRAIN_SHADER on Mountains (grass flat, rock steep, snow high;
  flat-shaded face normal from dFdx/dFdy, world space via viewMatrix) - needs re-authoring + a look

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… the header

- the floating node editor opens over part of the chat header, so the first
  drag (left+40) landed on another window: chat never moved and win:chat stayed
  null (the one red of the first run, 24/26 otherwise)
- dragHeader probes elementFromPoint along the handle for a header point

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- every control is the kit Button (icon/sm, outline/sm) with Icon names; the name field uses
  the kit field look (surface-inset, border-input, radius-input, focus ring)
- tokens only: check-tokens reports 0 for the file; spacing/type from --space-*/--fs-*
- suite: B waits for A s box before selecting it (7.2), and the saved swatch is asserted
  to be drawn in its own colour (5.2b)
- svelte-check 318/47 = baseline

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…#19, #17); --speaking in the theme keys + kit

- tokens.css: data-density=compact (desktop only) tightens --row-h/--control-h/--control-h-sm/--icon-button
  and the new --setting-row-pad-y/--nav-row-h to 32px rows; phones keep 44px targets.
  $lib/ui/density.js applyDensity (+ unit test); the Settings > Interface row is 37-settings'.
- /kit ships in every build as a lazy chunk (VITE_UI_KIT=0 drops it), with a 'Building a module UI?'
  card linking the docs page; Density segmented + ?density=compact deep link.
- --speaking joins REDESIGN_TOKENS (a .theme.json may set it) and the kit swatches.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
AlexZ005 and others added 28 commits October 6, 2026 17:42
…segmented controls fill their line, the content (not the back button) takes focus on open; inventory suite retries a re-rendered control and reports a page remount

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… the stop

- faceOf: the eye depth is the front-most HEAD triangle straight through each eye point (bind
  pose), not the max z near it - the knight's face sits recessed inside its helmet, so the stars
  floated 8 cm out and slid off the eyes seen from the side (now ~3 cm, measured on 4 characters)
- avatar-feet: the side screenshot waits for B to stop (a walking B left the frame)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ot after Scale)

The battery showed 9 reds, all the old 8-button arithmetic (checked rows, bar length, the
well index, and the reorder walk now needing five presses to cross the well). Re-run queued.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…so the 4th press crosses the well

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… (focus kept inside, a body-level fallback), the page last used comes back on reopen (resolve waits for the labels), 44 px segmented options on a phone; inventory walk split in two (8-minute runner cap); import-duplicates opens Explorer, vr-window-grab reads the schema's toast

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…entory

- SettingRow (kit): under 640px any row whose control is a Segmented takes the wide
  layout (control on its own full-width line). Interface > Density's two long options
  had squeezed its description into a one-word column; seven more rows had the shape.
- settings-layout: the phone section walks all 13 pages and fails when a description
  keeps under half its row.
- docs/settings-inventory.md: Density listed as an intentional NEW row (NOTES-38 #19)
  and `ui:density` under the Interface reset keys.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… in four parts

- SettingRow (kit): under 640px a row also stacks when its control holds a slider or two
  or more pieces (Apply + Reload, a field and its unit) - the r4 phone check found the
  volume/sensitivity sliders and Connection's Apply squeezing their descriptions.
  Explorer's "Show breakdown" row is marked wide.
- settings-inventory: split into four suites on the GPU backend (both halves were still
  killed by the runner's 8-minute cap under load, ~5 s a row on SwiftShader); each part
  checks it drove every listed row, and logs any row slower than 3 s.
- vr-passthrough: wait for the debug hook after the reload instead of a fixed 2.5 s.

A/B on pristine 1.25.0 (r4): dock-chrome 9.3, dock-inset, scene-switch-keep 1.1 and
vr-passthrough "exiting restores the preset sky" fail identically there - pre-existing.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ile other toasts come and go, so the card never read as 'stable' before the 8 s offer ran out

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…et settings appeared under the still-open Settings dialog

- Toasts.svelte: undo toasts render in the CRITICAL tier (--z-toast, where approvals live)
  instead of the regular one below modals, and are never folded into +N more; the card
  markup is one snippet shared by both tiers
- undo-toast presses Undo through the button itself (a mouse aimed at it raced the stack
  reflowing — measured: the press landed beside it and the offer expired) and asserts
  separately that the button is the topmost element at its centre, incl. with Settings open

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…2: one page call took seconds and the real 8 s offer expired before the press); expiry watched with a 3 s offer

- undoToast.undoTiming.ms (default UNDO_MS = 8000; only the debug hook writes it)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…y dim layer); Esc check waits for the close

- the non-modal dialog's dim layer (ui.css dialog.tp-modal-frame::before, z-index -1) paints
  inside the dialog's stacking context, above the dialog background, so the transparent header
  and content column showed it: invisible in dark, a grey window in light. .settings-shell
  takes var(--surface-1).
- settings-layout section 3: per theme, a screenshot strip of the content column's empty
  padding must match the dialog's colour (counterfactual: shell transparent -> 100% off).
- settings-layout "Esc closes Settings" waits for the dialog to hide (3 s cap) instead of a
  300 ms timer, and reports the focus, the store and where Escape travelled (measured 1054 ms
  on a loaded box; the probe shows the key reaching the window every time).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…37-int-126

# Conflicts:
#	src/lib/peerHandler.svelte.js
…nt-126

# Conflicts:
#	src/components/menu/Settings.svelte
#	src/components/menu/settings/AvatarSettings.svelte
…e flying in Play opt-in; Up/Down only show for a flying scene)
…fault bar was 402 px on a 393 px phone — every page scrolled sideways); layout-name field 16 px on phones; touch-actions allows flying after its reloads (R24)
…he two separate reads straddled B's camera flying back from the panel)
…(37 R1 stopped DragRow's blur re-commit — R26's 'Escape after typing reverts'); arrow steps from there
…nert) is not an offer — §4 found two .tp-toast--undo (strict mode)
…s reset — the defaults apply after a reload.')
…ply started 13.9 s after the press on a loaded dev server — stack-traced: undo → applySession → /clear all; a build takes ~2 s)
…esets and a new Settings) + moduleVersions.json (modules@2fcce49)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@AlexZ005
AlexZ005 merged commit 23e6376 into main Oct 7, 2026
6 checks passed
@AlexZ005
AlexZ005 deleted the feat/1.26 branch October 7, 2026 09:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant