diff --git a/apps/docs/content/releases/next.mdx b/apps/docs/content/releases/next.mdx
index c7cf4f2f1335..5a7fed2b5a40 100644
--- a/apps/docs/content/releases/next.mdx
+++ b/apps/docs/content/releases/next.mdx
@@ -273,6 +273,8 @@ New helpers `getOwnerDocument()` and `getOwnerWindow()` are exported from `@tldr
- Optimize geometry hot paths for hit testing: reduce allocations and function call overhead in `Vec`, `Edge2d`, `Circle2d`, `Arc2d`, `Polyline2d`, and intersection routines. Circle hit testing is up to 19x faster, polyline nearest-point is 6.8x faster. ([#8210](https://github.com/tldraw/tldraw/pull/8210))
- Exports now automatically trim to visual content bounds, capturing overflow like thick strokes and arrowheads without extra whitespace. ([#8202](https://github.com/tldraw/tldraw/pull/8202))
- Improve resize performance for multiple geo shapes with text labels by batching DOM measurements into a single pass per frame. ([#7949](https://github.com/tldraw/tldraw/pull/7949))
+- Allow Cmd+click / Ctrl+click on style panel items to apply style changes only to selected shapes without updating defaults for future shapes. ([#8452](https://github.com/tldraw/tldraw/pull/8452))
+- Hide selection overlay when nudging shapes with arrow keys. ([#8447](https://github.com/tldraw/tldraw/pull/8447))
- Replace `@use-gesture/react` dependency with custom gesture handling, reducing bundle size and eliminating a stale dependency. ([#8392](https://github.com/tldraw/tldraw/pull/8392))
- Tighten iframe referrer policy for embeds to send only the origin instead of the full URL to third-party embed providers. ([#8412](https://github.com/tldraw/tldraw/pull/8412))
- Move the debug mode toggle into the preferences submenu. ([#8259](https://github.com/tldraw/tldraw/pull/8259))
@@ -294,3 +296,9 @@ New helpers `getOwnerDocument()` and `getOwnerWindow()` are exported from `@tldr
- Fix right-clicking inside a multi-selection over a filled background shape changing the selection. ([#8434](https://github.com/tldraw/tldraw/pull/8434))
- Fix memory leak where the Editor was retained after unmount via a shared throttled `updateHoveredShapeId` closure. ([#8439](https://github.com/tldraw/tldraw/pull/8439))
- Fix pattern fill not scaling correctly with dynamic size mode. ([#8441](https://github.com/tldraw/tldraw/pull/8441))
+- Fix arrow labels rendered at incorrect size when editing at high zoom in dynamic size mode. ([#8451](https://github.com/tldraw/tldraw/pull/8451))
+- Fix shadow artifact and oversized caret on notes and geo shapes at high zoom in dynamic size mode. ([#8378](https://github.com/tldraw/tldraw/pull/8378))
+- Fix crash from duplicate fractional index keys in `kickoutOccludedShapes` during multiplayer sync. ([#8448](https://github.com/tldraw/tldraw/pull/8448))
+- Fix NaN propagation from zero-length labeled arrows causing all shapes to disappear. ([#8329](https://github.com/tldraw/tldraw/pull/8329))
+- Fix crash when isolating curved arrows with degenerate geometry. ([#8176](https://github.com/tldraw/tldraw/pull/8176))
+- Fix camera state stuck at 'moving' on dispose, blocking shape interactions on the next editor instance. ([#8396](https://github.com/tldraw/tldraw/pull/8396))
diff --git a/apps/docs/content/sdk-features/locked-shapes.mdx b/apps/docs/content/sdk-features/locked-shapes.mdx
index c81392904746..eaa728ce703c 100644
--- a/apps/docs/content/sdk-features/locked-shapes.mdx
+++ b/apps/docs/content/sdk-features/locked-shapes.mdx
@@ -115,4 +115,4 @@ When this returns `true`, double-clicking the locked shape enters edit mode, let
## Locking in the UI
-In the default tldraw UI, users can lock shapes through the context menu or the keyboard shortcut (`Shift+L`). Locked shapes display a lock indicator when hovered, and the context menu shows an unlock option.
+In the default tldraw UI, users can lock shapes through the context menu or the keyboard shortcut (`Shift+L`). Users can right-click on a locked shape to access the context menu, which shows an unlock option.
diff --git a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-flowchart-decision-light-1-chromium-linux.png b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-flowchart-decision-light-1-chromium-linux.png
index 23a60c13ac1a..ebd10aabdb90 100644
Binary files a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-flowchart-decision-light-1-chromium-linux.png and b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-flowchart-decision-light-1-chromium-linux.png differ
diff --git a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-flowchart-with-class-defs-light-1-chromium-linux.png b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-flowchart-with-class-defs-light-1-chromium-linux.png
index 4e3f169ac366..63882a73ab98 100644
Binary files a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-flowchart-with-class-defs-light-1-chromium-linux.png and b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-flowchart-with-class-defs-light-1-chromium-linux.png differ
diff --git a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-flowchart-with-custom-edge-styles-light-1-chromium-linux.png b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-flowchart-with-custom-edge-styles-light-1-chromium-linux.png
index b1dd0cc6e66d..d7e4a98f414b 100644
Binary files a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-flowchart-with-custom-edge-styles-light-1-chromium-linux.png and b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-flowchart-with-custom-edge-styles-light-1-chromium-linux.png differ
diff --git a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-flowchart-with-subgraphs-light-1-chromium-linux.png b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-flowchart-with-subgraphs-light-1-chromium-linux.png
index 424949d2eb98..47db950ed359 100644
Binary files a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-flowchart-with-subgraphs-light-1-chromium-linux.png and b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-flowchart-with-subgraphs-light-1-chromium-linux.png differ
diff --git a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-sequence-diagram-basics-light-1-chromium-linux.png b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-sequence-diagram-basics-light-1-chromium-linux.png
index a12e1f992667..2901f5984696 100644
Binary files a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-sequence-diagram-basics-light-1-chromium-linux.png and b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-sequence-diagram-basics-light-1-chromium-linux.png differ
diff --git a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-sequence-diagram-with-alt-light-1-chromium-linux.png b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-sequence-diagram-with-alt-light-1-chromium-linux.png
index 208a6b3e1d62..834c2f403f80 100644
Binary files a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-sequence-diagram-with-alt-light-1-chromium-linux.png and b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-sequence-diagram-with-alt-light-1-chromium-linux.png differ
diff --git a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-sequence-diagram-with-parallel-lanes-light-1-chromium-linux.png b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-sequence-diagram-with-parallel-lanes-light-1-chromium-linux.png
index bf1ad9ef4a99..5f0d17a25902 100644
Binary files a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-sequence-diagram-with-parallel-lanes-light-1-chromium-linux.png and b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-sequence-diagram-with-parallel-lanes-light-1-chromium-linux.png differ
diff --git a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-state-diagram-basic-light-1-chromium-linux.png b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-state-diagram-basic-light-1-chromium-linux.png
index 8c431c8a8528..7a1cf8c941a6 100644
Binary files a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-state-diagram-basic-light-1-chromium-linux.png and b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-state-diagram-basic-light-1-chromium-linux.png differ
diff --git a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-state-diagram-with-fork-join-light-1-chromium-linux.png b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-state-diagram-with-fork-join-light-1-chromium-linux.png
index eb02bf1f9de7..44369c501694 100644
Binary files a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-state-diagram-with-fork-join-light-1-chromium-linux.png and b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-state-diagram-with-fork-join-light-1-chromium-linux.png differ
diff --git a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-state-diagram-with-nested-state-light-1-chromium-linux.png b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-state-diagram-with-nested-state-light-1-chromium-linux.png
index 0059bd5f9345..8b91999b210f 100644
Binary files a/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-state-diagram-with-nested-state-light-1-chromium-linux.png and b/apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-state-diagram-with-nested-state-light-1-chromium-linux.png differ
diff --git a/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Geo-shapes-dark-1-Mobile-Chrome-linux.png b/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Geo-shapes-dark-1-Mobile-Chrome-linux.png
index 34164d9a56b4..075ad5fbc006 100644
Binary files a/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Geo-shapes-dark-1-Mobile-Chrome-linux.png and b/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Geo-shapes-dark-1-Mobile-Chrome-linux.png differ
diff --git a/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Geo-shapes-dark-1-chromium-linux.png b/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Geo-shapes-dark-1-chromium-linux.png
index 34164d9a56b4..075ad5fbc006 100644
Binary files a/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Geo-shapes-dark-1-chromium-linux.png and b/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Geo-shapes-dark-1-chromium-linux.png differ
diff --git a/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Geo-shapes-light-1-Mobile-Chrome-linux.png b/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Geo-shapes-light-1-Mobile-Chrome-linux.png
index 4ded440b4a35..f673d0fafe2a 100644
Binary files a/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Geo-shapes-light-1-Mobile-Chrome-linux.png and b/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Geo-shapes-light-1-Mobile-Chrome-linux.png differ
diff --git a/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Geo-shapes-light-1-chromium-linux.png b/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Geo-shapes-light-1-chromium-linux.png
index 4ded440b4a35..f673d0fafe2a 100644
Binary files a/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Geo-shapes-light-1-chromium-linux.png and b/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Geo-shapes-light-1-chromium-linux.png differ
diff --git a/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Regressions-dark-1-Mobile-Chrome-linux.png b/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Regressions-dark-1-Mobile-Chrome-linux.png
index b4a59e9ebcef..02c2b8f55b84 100644
Binary files a/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Regressions-dark-1-Mobile-Chrome-linux.png and b/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Regressions-dark-1-Mobile-Chrome-linux.png differ
diff --git a/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Regressions-dark-1-chromium-linux.png b/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Regressions-dark-1-chromium-linux.png
index 78a063bc8038..9d973b41730d 100644
Binary files a/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Regressions-dark-1-chromium-linux.png and b/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Regressions-dark-1-chromium-linux.png differ
diff --git a/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Regressions-light-1-Mobile-Chrome-linux.png b/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Regressions-light-1-Mobile-Chrome-linux.png
index 0c9bf4a0176a..11df23bf4e0c 100644
Binary files a/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Regressions-light-1-Mobile-Chrome-linux.png and b/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Regressions-light-1-Mobile-Chrome-linux.png differ
diff --git a/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Regressions-light-1-chromium-linux.png b/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Regressions-light-1-chromium-linux.png
index ef8af95fc494..619dafacc9b2 100644
Binary files a/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Regressions-light-1-chromium-linux.png and b/apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Regressions-light-1-chromium-linux.png differ
diff --git a/packages/tldraw/src/lib/shapes/shared/PathBuilder.test.tsx b/packages/tldraw/src/lib/shapes/shared/PathBuilder.test.tsx
index a6b7d2a9eb5a..40389b469159 100644
--- a/packages/tldraw/src/lib/shapes/shared/PathBuilder.test.tsx
+++ b/packages/tldraw/src/lib/shapes/shared/PathBuilder.test.tsx
@@ -105,11 +105,11 @@ describe('PathBuilder', () => {
.toSvg({ strokeWidth: 10, style: 'draw', randomSeed: '123' })
expect(path).toMatchInlineSnapshot(`
-
- `)
+
+ `)
const closed = new PathBuilder()
.moveTo(0, 0)
.lineTo(100, 100)
@@ -119,11 +119,11 @@ describe('PathBuilder', () => {
.toSvg({ strokeWidth: 10, style: 'draw', randomSeed: '123' })
expect(closed).toMatchInlineSnapshot(`
-
- `)
+
+ `)
})
})
diff --git a/packages/tldraw/src/lib/shapes/shared/PathBuilder.tsx b/packages/tldraw/src/lib/shapes/shared/PathBuilder.tsx
index 9141049d42d3..3623edc36b05 100644
--- a/packages/tldraw/src/lib/shapes/shared/PathBuilder.tsx
+++ b/packages/tldraw/src/lib/shapes/shared/PathBuilder.tsx
@@ -811,9 +811,14 @@ export class PathBuilder {
tangentToNext,
tangentToPrev,
} of drawCommands) {
- const offset = command.isClose
- ? lastMoveToOffset
- : { x: random() * offsetAmount, y: random() * offsetAmount }
+ let offset: VecLike
+ if (command.isClose) {
+ offset = lastMoveToOffset
+ } else {
+ const direction = new Vec(random(), random()).uni()
+ const magnitude = Math.sqrt(Math.abs(random())) * offsetAmount
+ offset = Vec.Mul(direction, magnitude)
+ }
if (command.type === 'move') {
lastMoveToOffset = offset