diff --git a/apps/editor/app/page.tsx b/apps/editor/app/page.tsx index a20826c03..e4ccf7ed3 100644 --- a/apps/editor/app/page.tsx +++ b/apps/editor/app/page.tsx @@ -29,7 +29,7 @@ const SIDEBAR_TABS = [ alt="" className="h-8 w-8 object-contain" height={32} - src="/icons/scene.png" + src="/icons/scene.webp" width={32} /> ), @@ -45,7 +45,7 @@ const SIDEBAR_TABS = [ alt="" className="h-8 w-8 object-contain" height={32} - src="/icons/build.png" + src="/icons/build.webp" width={32} /> ), @@ -61,7 +61,7 @@ const SIDEBAR_TABS = [ alt="" className="h-8 w-8 object-contain" height={32} - src="/icons/couch.png" + src="/icons/couch.webp" width={32} /> ), @@ -77,7 +77,7 @@ const SIDEBAR_TABS = [ alt="" className="h-8 w-8 object-contain" height={32} - src="/icons/settings.png" + src="/icons/settings.webp" width={32} /> ), diff --git a/apps/editor/components/build-tab.tsx b/apps/editor/components/build-tab.tsx index 0fb0db5c2..99fb55d98 100644 --- a/apps/editor/components/build-tab.tsx +++ b/apps/editor/components/build-tab.tsx @@ -68,38 +68,38 @@ type MepItem = { // Same icons + ordering as the community Build sidebar, minus presets. const BUILD_TYPES: BuildType[] = [ - { id: 'wall', label: 'Wall', iconSrc: '/icons/wall.png', kind: 'wall' }, - { id: 'fence', label: 'Fence', iconSrc: '/icons/fence.png', kind: 'fence' }, - { id: 'slab', label: 'Slab', iconSrc: '/icons/floor.png', kind: 'slab' }, - { id: 'ceiling', label: 'Ceiling', iconSrc: '/icons/ceiling.png', kind: 'ceiling' }, - { id: 'roof', label: 'Roof', iconSrc: '/icons/roof.png', kind: 'roof' }, - { id: 'stair', label: 'Stairs', iconSrc: '/icons/stairs.png', kind: 'stair' }, - { id: 'elevator', label: 'Elevator', iconSrc: '/icons/elevator.png', kind: 'elevator' }, - { id: 'door', label: 'Door', iconSrc: '/icons/door.png', kind: 'door' }, - { id: 'window', label: 'Window', iconSrc: '/icons/window.png', kind: 'window' }, - { id: 'column', label: 'Column', iconSrc: '/icons/column.png', kind: 'column' }, - { id: 'shelf', label: 'Shelf', iconSrc: '/icons/shelf.png', kind: 'shelf' }, - { id: 'spawn', label: 'Spawn Point', iconSrc: '/icons/spawn-point.png', kind: 'spawn' }, + { id: 'wall', label: 'Wall', iconSrc: '/icons/wall.webp', kind: 'wall' }, + { id: 'fence', label: 'Fence', iconSrc: '/icons/fence.webp', kind: 'fence' }, + { id: 'slab', label: 'Slab', iconSrc: '/icons/floor.webp', kind: 'slab' }, + { id: 'ceiling', label: 'Ceiling', iconSrc: '/icons/ceiling.webp', kind: 'ceiling' }, + { id: 'roof', label: 'Roof', iconSrc: '/icons/roof.webp', kind: 'roof' }, + { id: 'stair', label: 'Stairs', iconSrc: '/icons/stairs.webp', kind: 'stair' }, + { id: 'elevator', label: 'Elevator', iconSrc: '/icons/elevator.webp', kind: 'elevator' }, + { id: 'door', label: 'Door', iconSrc: '/icons/door.webp', kind: 'door' }, + { id: 'window', label: 'Window', iconSrc: '/icons/window.webp', kind: 'window' }, + { id: 'column', label: 'Column', iconSrc: '/icons/column.webp', kind: 'column' }, + { id: 'shelf', label: 'Shelf', iconSrc: '/icons/shelf.webp', kind: 'shelf' }, + { id: 'spawn', label: 'Spawn Point', iconSrc: '/icons/spawn-point.webp', kind: 'spawn' }, // Group tile — no tool of its own; opens the MEP sub-grid below (like Roof). - { id: 'mep', label: 'MEP', iconSrc: '/icons/HVAC.png' }, - { id: 'painting', label: 'Painting', iconSrc: '/icons/paint.png', mode: 'material-paint' }, + { id: 'mep', label: 'MEP', iconSrc: '/icons/HVAC.webp' }, + { id: 'painting', label: 'Painting', iconSrc: '/icons/paint.webp', mode: 'material-paint' }, ] // MEP sub-grid surfaced under the "MEP" tile — same icons + ordering the MEP // tools had in the community Build sidebar. const MEP_ITEMS: MepItem[] = [ - { id: 'duct-segment', label: 'Duct', iconSrc: '/icons/duct.png', kind: 'duct-segment' }, + { id: 'duct-segment', label: 'Duct', iconSrc: '/icons/duct.webp', kind: 'duct-segment' }, { id: 'duct-terminal', label: 'Register', - iconSrc: '/icons/registers.png', + iconSrc: '/icons/registers.webp', kind: 'duct-terminal', }, - { id: 'hvac-equipment', label: 'HVAC Unit', iconSrc: '/icons/HVAC.png', kind: 'hvac-equipment' }, - { id: 'lineset', label: 'Lineset', iconSrc: '/icons/lineset.png', kind: 'lineset' }, - { id: 'liquid-line', label: 'Liquid Line', iconSrc: '/icons/lineset.png', kind: 'liquid-line' }, - { id: 'pipe-segment', label: 'DWV Pipe', iconSrc: '/icons/dwv-pipes.png', kind: 'pipe-segment' }, - { id: 'pipe-trap', label: 'Trap', iconSrc: '/icons/dwv-pipes.png', kind: 'pipe-trap' }, + { id: 'hvac-equipment', label: 'HVAC Unit', iconSrc: '/icons/HVAC.webp', kind: 'hvac-equipment' }, + { id: 'lineset', label: 'Lineset', iconSrc: '/icons/lineset.webp', kind: 'lineset' }, + { id: 'liquid-line', label: 'Liquid Line', iconSrc: '/icons/lineset.webp', kind: 'liquid-line' }, + { id: 'pipe-segment', label: 'DWV Pipe', iconSrc: '/icons/dwv-pipes.webp', kind: 'pipe-segment' }, + { id: 'pipe-trap', label: 'Trap', iconSrc: '/icons/dwv-pipes.webp', kind: 'pipe-trap' }, ] /** @@ -126,7 +126,7 @@ function activatePaintMode(): void { type RoofFeature = { kind: string; label: string; iconSrc: string } -const ROOF_FEATURE_FALLBACK_ICON = '/icons/roof.png' +const ROOF_FEATURE_FALLBACK_ICON = '/icons/roof.webp' /** * Roof accessories surfaced under the Roof tile (a "Features" group). Unlike @@ -386,7 +386,7 @@ export function BuildTab() { aria-hidden className="size-4 object-contain" height={16} - src="/icons/duct-fitting.png" + src="/icons/duct-fitting.webp" width={16} /> Add Fitting @@ -416,7 +416,7 @@ export function BuildTab() { aria-hidden className="size-4 object-contain" height={16} - src="/icons/duct-fitting.png" + src="/icons/duct-fitting.webp" width={16} /> Add Fitting diff --git a/apps/editor/components/scene-loader.tsx b/apps/editor/components/scene-loader.tsx index 0a602be11..34acd2e2d 100644 --- a/apps/editor/components/scene-loader.tsx +++ b/apps/editor/components/scene-loader.tsx @@ -42,7 +42,7 @@ const SIDEBAR_TABS: (SidebarTab & { component: React.ComponentType })[] = [ alt="" className="h-8 w-8 object-contain" height={32} - src="/icons/scene.png" + src="/icons/scene.webp" width={32} /> ), @@ -58,7 +58,7 @@ const SIDEBAR_TABS: (SidebarTab & { component: React.ComponentType })[] = [ alt="" className="h-8 w-8 object-contain" height={32} - src="/icons/build.png" + src="/icons/build.webp" width={32} /> ), diff --git a/apps/editor/components/viewer-toolbar.tsx b/apps/editor/components/viewer-toolbar.tsx index 49638840a..225f7237b 100644 --- a/apps/editor/components/viewer-toolbar.tsx +++ b/apps/editor/components/viewer-toolbar.tsx @@ -86,7 +86,7 @@ const VIEW_MODES: { id: ViewMode; label: string; icon: React.ReactNode }[] = [ alt="" className="h-3.5 w-3.5 object-contain" height={14} - src="/icons/building.png" + src="/icons/building.webp" width={14} /> ), @@ -99,7 +99,7 @@ const VIEW_MODES: { id: ViewMode; label: string; icon: React.ReactNode }[] = [ alt="" className="h-3.5 w-3.5 object-contain" height={14} - src="/icons/blueprint.png" + src="/icons/blueprint.webp" width={14} /> ), @@ -121,9 +121,9 @@ const levelModeLabels: Record = { const wallModeOrder = ['cutaway', 'up', 'down'] as const const wallModeConfig: Record = { - up: { icon: '/icons/room.png', label: 'Full height' }, - cutaway: { icon: '/icons/wallcut.png', label: 'Cutaway' }, - down: { icon: '/icons/walllow.png', label: 'Low' }, + up: { icon: '/icons/room.webp', label: 'Full height' }, + cutaway: { icon: '/icons/wallcut.webp', label: 'Cutaway' }, + down: { icon: '/icons/walllow.webp', label: 'Low' }, } const SHADING_OPTIONS = [ diff --git a/apps/editor/public/icons/HVAC.png b/apps/editor/public/icons/HVAC.png deleted file mode 100644 index c846c3eea..000000000 Binary files a/apps/editor/public/icons/HVAC.png and /dev/null differ diff --git a/apps/editor/public/icons/HVAC.webp b/apps/editor/public/icons/HVAC.webp new file mode 100644 index 000000000..38514409c Binary files /dev/null and b/apps/editor/public/icons/HVAC.webp differ diff --git a/apps/editor/public/icons/appliance.png b/apps/editor/public/icons/appliance.png deleted file mode 100644 index c2bb0bae3..000000000 Binary files a/apps/editor/public/icons/appliance.png and /dev/null differ diff --git a/apps/editor/public/icons/appliance.webp b/apps/editor/public/icons/appliance.webp new file mode 100644 index 000000000..7d729ebc6 Binary files /dev/null and b/apps/editor/public/icons/appliance.webp differ diff --git a/apps/editor/public/icons/bathroom.png b/apps/editor/public/icons/bathroom.png deleted file mode 100644 index fafec7cc4..000000000 Binary files a/apps/editor/public/icons/bathroom.png and /dev/null differ diff --git a/apps/editor/public/icons/bathroom.webp b/apps/editor/public/icons/bathroom.webp new file mode 100644 index 000000000..e913c3dc2 Binary files /dev/null and b/apps/editor/public/icons/bathroom.webp differ diff --git a/apps/editor/public/icons/blueprint.png b/apps/editor/public/icons/blueprint.png deleted file mode 100644 index 6df91b1e8..000000000 Binary files a/apps/editor/public/icons/blueprint.png and /dev/null differ diff --git a/apps/editor/public/icons/blueprint.webp b/apps/editor/public/icons/blueprint.webp new file mode 100644 index 000000000..ee0f60dbf Binary files /dev/null and b/apps/editor/public/icons/blueprint.webp differ diff --git a/apps/editor/public/icons/build.png b/apps/editor/public/icons/build.png deleted file mode 100644 index cfaead987..000000000 Binary files a/apps/editor/public/icons/build.png and /dev/null differ diff --git a/apps/editor/public/icons/build.webp b/apps/editor/public/icons/build.webp new file mode 100644 index 000000000..0f57eb3fd Binary files /dev/null and b/apps/editor/public/icons/build.webp differ diff --git a/apps/editor/public/icons/building.png b/apps/editor/public/icons/building.png deleted file mode 100644 index 1d3776807..000000000 Binary files a/apps/editor/public/icons/building.png and /dev/null differ diff --git a/apps/editor/public/icons/building.webp b/apps/editor/public/icons/building.webp new file mode 100644 index 000000000..6aea0ab14 Binary files /dev/null and b/apps/editor/public/icons/building.webp differ diff --git a/apps/editor/public/icons/ceiling.png b/apps/editor/public/icons/ceiling.png deleted file mode 100644 index 9e04d6394..000000000 Binary files a/apps/editor/public/icons/ceiling.png and /dev/null differ diff --git a/apps/editor/public/icons/ceiling.webp b/apps/editor/public/icons/ceiling.webp new file mode 100644 index 000000000..3abfa4cfb Binary files /dev/null and b/apps/editor/public/icons/ceiling.webp differ diff --git a/apps/editor/public/icons/collection.png b/apps/editor/public/icons/collection.png deleted file mode 100644 index 32b7ccd09..000000000 Binary files a/apps/editor/public/icons/collection.png and /dev/null differ diff --git a/apps/editor/public/icons/collection.webp b/apps/editor/public/icons/collection.webp new file mode 100644 index 000000000..af45600c2 Binary files /dev/null and b/apps/editor/public/icons/collection.webp differ diff --git a/apps/editor/public/icons/column.png b/apps/editor/public/icons/column.png deleted file mode 100644 index 0e337b7f1..000000000 Binary files a/apps/editor/public/icons/column.png and /dev/null differ diff --git a/apps/editor/public/icons/column.webp b/apps/editor/public/icons/column.webp new file mode 100644 index 000000000..6259cc30d Binary files /dev/null and b/apps/editor/public/icons/column.webp differ diff --git a/apps/editor/public/icons/column1.png b/apps/editor/public/icons/column1.png deleted file mode 100644 index 8e44f6d8e..000000000 Binary files a/apps/editor/public/icons/column1.png and /dev/null differ diff --git a/apps/editor/public/icons/column1.webp b/apps/editor/public/icons/column1.webp new file mode 100644 index 000000000..27db894e3 Binary files /dev/null and b/apps/editor/public/icons/column1.webp differ diff --git a/apps/editor/public/icons/couch.png b/apps/editor/public/icons/couch.png deleted file mode 100644 index 6509e0057..000000000 Binary files a/apps/editor/public/icons/couch.png and /dev/null differ diff --git a/apps/editor/public/icons/couch.webp b/apps/editor/public/icons/couch.webp new file mode 100644 index 000000000..1f7a8e345 Binary files /dev/null and b/apps/editor/public/icons/couch.webp differ diff --git a/apps/editor/public/icons/cube.png b/apps/editor/public/icons/cube.png deleted file mode 100644 index c279d41b8..000000000 Binary files a/apps/editor/public/icons/cube.png and /dev/null differ diff --git a/apps/editor/public/icons/cube.webp b/apps/editor/public/icons/cube.webp new file mode 100644 index 000000000..b9922c132 Binary files /dev/null and b/apps/editor/public/icons/cube.webp differ diff --git a/apps/editor/public/icons/custom-room.png b/apps/editor/public/icons/custom-room.png deleted file mode 100644 index 14d40459f..000000000 Binary files a/apps/editor/public/icons/custom-room.png and /dev/null differ diff --git a/apps/editor/public/icons/custom-room.webp b/apps/editor/public/icons/custom-room.webp new file mode 100644 index 000000000..97bc509f0 Binary files /dev/null and b/apps/editor/public/icons/custom-room.webp differ diff --git a/apps/editor/public/icons/door.png b/apps/editor/public/icons/door.png deleted file mode 100644 index 8b0452465..000000000 Binary files a/apps/editor/public/icons/door.png and /dev/null differ diff --git a/apps/editor/public/icons/door.webp b/apps/editor/public/icons/door.webp new file mode 100644 index 000000000..7d6980fe5 Binary files /dev/null and b/apps/editor/public/icons/door.webp differ diff --git a/apps/editor/public/icons/duct-fitting.png b/apps/editor/public/icons/duct-fitting.png deleted file mode 100644 index f95b799ad..000000000 Binary files a/apps/editor/public/icons/duct-fitting.png and /dev/null differ diff --git a/apps/editor/public/icons/duct-fitting.webp b/apps/editor/public/icons/duct-fitting.webp new file mode 100644 index 000000000..43a76fc62 Binary files /dev/null and b/apps/editor/public/icons/duct-fitting.webp differ diff --git a/apps/editor/public/icons/duct.png b/apps/editor/public/icons/duct.png deleted file mode 100644 index b7f95f722..000000000 Binary files a/apps/editor/public/icons/duct.png and /dev/null differ diff --git a/apps/editor/public/icons/duct.webp b/apps/editor/public/icons/duct.webp new file mode 100644 index 000000000..0d0e2579c Binary files /dev/null and b/apps/editor/public/icons/duct.webp differ diff --git a/apps/editor/public/icons/dwv-pipes.png b/apps/editor/public/icons/dwv-pipes.png deleted file mode 100644 index 06bd1381c..000000000 Binary files a/apps/editor/public/icons/dwv-pipes.png and /dev/null differ diff --git a/apps/editor/public/icons/dwv-pipes.webp b/apps/editor/public/icons/dwv-pipes.webp new file mode 100644 index 000000000..85e3d60f5 Binary files /dev/null and b/apps/editor/public/icons/dwv-pipes.webp differ diff --git a/apps/editor/public/icons/elevator.png b/apps/editor/public/icons/elevator.png deleted file mode 100644 index d0278d622..000000000 Binary files a/apps/editor/public/icons/elevator.png and /dev/null differ diff --git a/apps/editor/public/icons/elevator.webp b/apps/editor/public/icons/elevator.webp new file mode 100644 index 000000000..51cf8e14c Binary files /dev/null and b/apps/editor/public/icons/elevator.webp differ diff --git a/apps/editor/public/icons/environment.png b/apps/editor/public/icons/environment.png deleted file mode 100644 index 2bc71b118..000000000 Binary files a/apps/editor/public/icons/environment.png and /dev/null differ diff --git a/apps/editor/public/icons/environment.webp b/apps/editor/public/icons/environment.webp new file mode 100644 index 000000000..b67f8d32d Binary files /dev/null and b/apps/editor/public/icons/environment.webp differ diff --git a/apps/editor/public/icons/fence.png b/apps/editor/public/icons/fence.png deleted file mode 100644 index 47f677f58..000000000 Binary files a/apps/editor/public/icons/fence.png and /dev/null differ diff --git a/apps/editor/public/icons/fence.webp b/apps/editor/public/icons/fence.webp new file mode 100644 index 000000000..ba63a1df8 Binary files /dev/null and b/apps/editor/public/icons/fence.webp differ diff --git a/apps/editor/public/icons/floor.png b/apps/editor/public/icons/floor.png deleted file mode 100644 index f2ce9f496..000000000 Binary files a/apps/editor/public/icons/floor.png and /dev/null differ diff --git a/apps/editor/public/icons/floor.webp b/apps/editor/public/icons/floor.webp new file mode 100644 index 000000000..3796b1c8a Binary files /dev/null and b/apps/editor/public/icons/floor.webp differ diff --git a/apps/editor/public/icons/floorplan.png b/apps/editor/public/icons/floorplan.png deleted file mode 100644 index 456dce36b..000000000 Binary files a/apps/editor/public/icons/floorplan.png and /dev/null differ diff --git a/apps/editor/public/icons/floorplan.webp b/apps/editor/public/icons/floorplan.webp new file mode 100644 index 000000000..4343774b3 Binary files /dev/null and b/apps/editor/public/icons/floorplan.webp differ diff --git a/apps/editor/public/icons/item.png b/apps/editor/public/icons/item.png deleted file mode 100644 index ae3fdc255..000000000 Binary files a/apps/editor/public/icons/item.png and /dev/null differ diff --git a/apps/editor/public/icons/item.webp b/apps/editor/public/icons/item.webp new file mode 100644 index 000000000..972ad4f4c Binary files /dev/null and b/apps/editor/public/icons/item.webp differ diff --git a/apps/editor/public/icons/kitchen.png b/apps/editor/public/icons/kitchen.png deleted file mode 100644 index 1bffefe4e..000000000 Binary files a/apps/editor/public/icons/kitchen.png and /dev/null differ diff --git a/apps/editor/public/icons/kitchen.webp b/apps/editor/public/icons/kitchen.webp new file mode 100644 index 000000000..8b2084a86 Binary files /dev/null and b/apps/editor/public/icons/kitchen.webp differ diff --git a/apps/editor/public/icons/level.png b/apps/editor/public/icons/level.png deleted file mode 100644 index 4b931fd08..000000000 Binary files a/apps/editor/public/icons/level.png and /dev/null differ diff --git a/apps/editor/public/icons/level.webp b/apps/editor/public/icons/level.webp new file mode 100644 index 000000000..6537ebd90 Binary files /dev/null and b/apps/editor/public/icons/level.webp differ diff --git a/apps/editor/public/icons/lineset.png b/apps/editor/public/icons/lineset.png deleted file mode 100644 index 755e7899b..000000000 Binary files a/apps/editor/public/icons/lineset.png and /dev/null differ diff --git a/apps/editor/public/icons/lineset.webp b/apps/editor/public/icons/lineset.webp new file mode 100644 index 000000000..fe1084f90 Binary files /dev/null and b/apps/editor/public/icons/lineset.webp differ diff --git a/apps/editor/public/icons/mesh.png b/apps/editor/public/icons/mesh.png deleted file mode 100644 index ecd7a21e2..000000000 Binary files a/apps/editor/public/icons/mesh.png and /dev/null differ diff --git a/apps/editor/public/icons/mesh.webp b/apps/editor/public/icons/mesh.webp new file mode 100644 index 000000000..0f5ee2972 Binary files /dev/null and b/apps/editor/public/icons/mesh.webp differ diff --git a/apps/editor/public/icons/orbit.png b/apps/editor/public/icons/orbit.png deleted file mode 100644 index d47d9d8c4..000000000 Binary files a/apps/editor/public/icons/orbit.png and /dev/null differ diff --git a/apps/editor/public/icons/orbit.webp b/apps/editor/public/icons/orbit.webp new file mode 100644 index 000000000..60e428d71 Binary files /dev/null and b/apps/editor/public/icons/orbit.webp differ diff --git a/apps/editor/public/icons/paint.png b/apps/editor/public/icons/paint.png deleted file mode 100644 index d66167bb0..000000000 Binary files a/apps/editor/public/icons/paint.png and /dev/null differ diff --git a/apps/editor/public/icons/paint.webp b/apps/editor/public/icons/paint.webp new file mode 100644 index 000000000..1c5a83cc6 Binary files /dev/null and b/apps/editor/public/icons/paint.webp differ diff --git a/apps/editor/public/icons/pan.png b/apps/editor/public/icons/pan.png deleted file mode 100644 index 8cf276a95..000000000 Binary files a/apps/editor/public/icons/pan.png and /dev/null differ diff --git a/apps/editor/public/icons/pan.webp b/apps/editor/public/icons/pan.webp new file mode 100644 index 000000000..4b5b58091 Binary files /dev/null and b/apps/editor/public/icons/pan.webp differ diff --git a/apps/editor/public/icons/registers.png b/apps/editor/public/icons/registers.png deleted file mode 100644 index faf1ad71c..000000000 Binary files a/apps/editor/public/icons/registers.png and /dev/null differ diff --git a/apps/editor/public/icons/registers.webp b/apps/editor/public/icons/registers.webp new file mode 100644 index 000000000..b36f090c9 Binary files /dev/null and b/apps/editor/public/icons/registers.webp differ diff --git a/apps/editor/public/icons/roof.png b/apps/editor/public/icons/roof.png deleted file mode 100644 index 253c1d763..000000000 Binary files a/apps/editor/public/icons/roof.png and /dev/null differ diff --git a/apps/editor/public/icons/roof.webp b/apps/editor/public/icons/roof.webp new file mode 100644 index 000000000..2d40e1710 Binary files /dev/null and b/apps/editor/public/icons/roof.webp differ diff --git a/apps/editor/public/icons/room.png b/apps/editor/public/icons/room.png deleted file mode 100644 index 85a179b48..000000000 Binary files a/apps/editor/public/icons/room.png and /dev/null differ diff --git a/apps/editor/public/icons/room.webp b/apps/editor/public/icons/room.webp new file mode 100644 index 000000000..d43ed6e86 Binary files /dev/null and b/apps/editor/public/icons/room.webp differ diff --git a/apps/editor/public/icons/rotate.png b/apps/editor/public/icons/rotate.png deleted file mode 100644 index 4b840d2f7..000000000 Binary files a/apps/editor/public/icons/rotate.png and /dev/null differ diff --git a/apps/editor/public/icons/rotate.webp b/apps/editor/public/icons/rotate.webp new file mode 100644 index 000000000..2e9f00377 Binary files /dev/null and b/apps/editor/public/icons/rotate.webp differ diff --git a/apps/editor/public/icons/scene.png b/apps/editor/public/icons/scene.png deleted file mode 100644 index 99036b8c2..000000000 Binary files a/apps/editor/public/icons/scene.png and /dev/null differ diff --git a/apps/editor/public/icons/scene.webp b/apps/editor/public/icons/scene.webp new file mode 100644 index 000000000..8a5cdd78d Binary files /dev/null and b/apps/editor/public/icons/scene.webp differ diff --git a/apps/editor/public/icons/select.png b/apps/editor/public/icons/select.png deleted file mode 100644 index 9abd1db38..000000000 Binary files a/apps/editor/public/icons/select.png and /dev/null differ diff --git a/apps/editor/public/icons/select.webp b/apps/editor/public/icons/select.webp new file mode 100644 index 000000000..85a59f7f7 Binary files /dev/null and b/apps/editor/public/icons/select.webp differ diff --git a/apps/editor/public/icons/settings.png b/apps/editor/public/icons/settings.png deleted file mode 100644 index 14cb0c68a..000000000 Binary files a/apps/editor/public/icons/settings.png and /dev/null differ diff --git a/apps/editor/public/icons/settings.webp b/apps/editor/public/icons/settings.webp new file mode 100644 index 000000000..66c7765e7 Binary files /dev/null and b/apps/editor/public/icons/settings.webp differ diff --git a/apps/editor/public/icons/shelf.png b/apps/editor/public/icons/shelf.png deleted file mode 100644 index 84845573c..000000000 Binary files a/apps/editor/public/icons/shelf.png and /dev/null differ diff --git a/apps/editor/public/icons/shelf.webp b/apps/editor/public/icons/shelf.webp new file mode 100644 index 000000000..0f7a0a648 Binary files /dev/null and b/apps/editor/public/icons/shelf.webp differ diff --git a/apps/editor/public/icons/site-flag.png b/apps/editor/public/icons/site-flag.png deleted file mode 100644 index 593e71924..000000000 Binary files a/apps/editor/public/icons/site-flag.png and /dev/null differ diff --git a/apps/editor/public/icons/site-flag.webp b/apps/editor/public/icons/site-flag.webp new file mode 100644 index 000000000..fbb25ca24 Binary files /dev/null and b/apps/editor/public/icons/site-flag.webp differ diff --git a/apps/editor/public/icons/site.png b/apps/editor/public/icons/site.png deleted file mode 100644 index 0d37688ae..000000000 Binary files a/apps/editor/public/icons/site.png and /dev/null differ diff --git a/apps/editor/public/icons/site.webp b/apps/editor/public/icons/site.webp new file mode 100644 index 000000000..46f038a19 Binary files /dev/null and b/apps/editor/public/icons/site.webp differ diff --git a/apps/editor/public/icons/spawn-point.png b/apps/editor/public/icons/spawn-point.png deleted file mode 100644 index 0c2b05d35..000000000 Binary files a/apps/editor/public/icons/spawn-point.png and /dev/null differ diff --git a/apps/editor/public/icons/spawn-point.webp b/apps/editor/public/icons/spawn-point.webp new file mode 100644 index 000000000..0b34c36f1 Binary files /dev/null and b/apps/editor/public/icons/spawn-point.webp differ diff --git a/apps/editor/public/icons/stairs.png b/apps/editor/public/icons/stairs.png deleted file mode 100644 index 6c9f1a65e..000000000 Binary files a/apps/editor/public/icons/stairs.png and /dev/null differ diff --git a/apps/editor/public/icons/stairs.webp b/apps/editor/public/icons/stairs.webp new file mode 100644 index 000000000..efd133b85 Binary files /dev/null and b/apps/editor/public/icons/stairs.webp differ diff --git a/apps/editor/public/icons/topview.png b/apps/editor/public/icons/topview.png deleted file mode 100644 index 35c96248d..000000000 Binary files a/apps/editor/public/icons/topview.png and /dev/null differ diff --git a/apps/editor/public/icons/topview.webp b/apps/editor/public/icons/topview.webp new file mode 100644 index 000000000..91920a201 Binary files /dev/null and b/apps/editor/public/icons/topview.webp differ diff --git a/apps/editor/public/icons/tree.png b/apps/editor/public/icons/tree.png deleted file mode 100644 index ae3fdc255..000000000 Binary files a/apps/editor/public/icons/tree.png and /dev/null differ diff --git a/apps/editor/public/icons/tree.webp b/apps/editor/public/icons/tree.webp new file mode 100644 index 000000000..972ad4f4c Binary files /dev/null and b/apps/editor/public/icons/tree.webp differ diff --git a/apps/editor/public/icons/wall.png b/apps/editor/public/icons/wall.png deleted file mode 100644 index 465e3e9d8..000000000 Binary files a/apps/editor/public/icons/wall.png and /dev/null differ diff --git a/apps/editor/public/icons/wall.webp b/apps/editor/public/icons/wall.webp new file mode 100644 index 000000000..78649e521 Binary files /dev/null and b/apps/editor/public/icons/wall.webp differ diff --git a/apps/editor/public/icons/wallcut.png b/apps/editor/public/icons/wallcut.png deleted file mode 100644 index bedcf6145..000000000 Binary files a/apps/editor/public/icons/wallcut.png and /dev/null differ diff --git a/apps/editor/public/icons/wallcut.webp b/apps/editor/public/icons/wallcut.webp new file mode 100644 index 000000000..cd089d5d8 Binary files /dev/null and b/apps/editor/public/icons/wallcut.webp differ diff --git a/apps/editor/public/icons/walllow.png b/apps/editor/public/icons/walllow.png deleted file mode 100644 index 7ec71abd4..000000000 Binary files a/apps/editor/public/icons/walllow.png and /dev/null differ diff --git a/apps/editor/public/icons/walllow.webp b/apps/editor/public/icons/walllow.webp new file mode 100644 index 000000000..427eafa28 Binary files /dev/null and b/apps/editor/public/icons/walllow.webp differ diff --git a/apps/editor/public/icons/window.png b/apps/editor/public/icons/window.png deleted file mode 100644 index ec62d0a7d..000000000 Binary files a/apps/editor/public/icons/window.png and /dev/null differ diff --git a/apps/editor/public/icons/window.webp b/apps/editor/public/icons/window.webp new file mode 100644 index 000000000..4fc1c060a Binary files /dev/null and b/apps/editor/public/icons/window.webp differ diff --git a/apps/editor/public/icons/zone.png b/apps/editor/public/icons/zone.png deleted file mode 100644 index 32b7ccd09..000000000 Binary files a/apps/editor/public/icons/zone.png and /dev/null differ diff --git a/apps/editor/public/icons/zone.webp b/apps/editor/public/icons/zone.webp new file mode 100644 index 000000000..af45600c2 Binary files /dev/null and b/apps/editor/public/icons/zone.webp differ diff --git a/packages/editor/src/components/editor-2d/floorplan-cursor-indicator-overlay.tsx b/packages/editor/src/components/editor-2d/floorplan-cursor-indicator-overlay.tsx index 731925fa5..80a672db6 100644 --- a/packages/editor/src/components/editor-2d/floorplan-cursor-indicator-overlay.tsx +++ b/packages/editor/src/components/editor-2d/floorplan-cursor-indicator-overlay.tsx @@ -77,7 +77,7 @@ export const FloorplanCursorIndicatorOverlay = memo(function FloorplanCursorIndi } if (mode === 'material-paint') { - return { kind: 'asset', iconSrc: '/icons/paint.png' } + return { kind: 'asset', iconSrc: '/icons/paint.webp' } } return null diff --git a/packages/editor/src/components/editor/index.tsx b/packages/editor/src/components/editor/index.tsx index ca6dde067..3c8b1d590 100644 --- a/packages/editor/src/components/editor/index.tsx +++ b/packages/editor/src/components/editor/index.tsx @@ -569,7 +569,7 @@ function PaintCursorBadge({ alt="" aria-hidden="true" className="h-5 w-5 object-contain drop-shadow-[0_2px_4px_rgba(0,0,0,0.5)]" - src="/icons/paint.png" + src="/icons/paint.webp" /> @@ -601,10 +601,14 @@ const ViewerSceneContent = memo(function ViewerSceneContent({ }) { // Studio mode is a clean render/snapshot surface — no selection or editing // affordances. It mirrors version-preview's chrome gating on the canvas. - const noEditing = isVersionPreviewMode || isFirstPersonMode || isStudioMode + // Capture (snapshot) mode is camera-only for the same reason: suppress + // selection, editing handles, and the tool manager (which mounts the site + // boundary flags) so the framed shot stays clean. + const isCaptureMode = useEditor((s) => s.isCaptureMode) + const noEditing = isVersionPreviewMode || isFirstPersonMode || isStudioMode || isCaptureMode return ( <> - {!(isFirstPersonMode || isStudioMode) && } + {!(isFirstPersonMode || isStudioMode || isCaptureMode) && } {!noEditing && } {!noEditing && } {!noEditing && } diff --git a/packages/editor/src/components/systems/zone/zone-system.tsx b/packages/editor/src/components/systems/zone/zone-system.tsx index e42ac3858..98e68b6cf 100644 --- a/packages/editor/src/components/systems/zone/zone-system.tsx +++ b/packages/editor/src/components/systems/zone/zone-system.tsx @@ -16,6 +16,9 @@ export const ZoneSystem = () => { const selectedLevelId = useViewer.getState().selection.levelId const selectedZoneId = useViewer.getState().selection.zoneId const hoveredId = useViewer.getState().hoveredId + // Snapshot capture is a clean, camera-only surface — never show zone + // geometry or the HTML zone tags in the framed shot. + const isCaptureMode = useEditor.getState().isCaptureMode const zoneGeometryVisible = structureLayer === 'zones' const zones = sceneRegistry.byType.zone || new Set() @@ -35,8 +38,14 @@ export const ZoneSystem = () => { // Keep group visible (so labels stay active), hide/show meshes only. // Show meshes when: in zone mode, selected, or delete-hovered. if (!obj.visible) obj.visible = true - const meshVisible = zoneGeometryVisible || isSelected || isDeleteHovered - const targetOpacity = isSelected || isDeleteHovered ? 1 : zoneGeometryVisible ? 1 : 0 + const meshVisible = !isCaptureMode && (zoneGeometryVisible || isSelected || isDeleteHovered) + const targetOpacity = isCaptureMode + ? 0 + : isSelected || isDeleteHovered + ? 1 + : zoneGeometryVisible + ? 1 + : 0 const walls = (obj as Group).getObjectByName('walls') as Mesh | undefined if (walls) { @@ -73,8 +82,9 @@ export const ZoneSystem = () => { obj.userData.__raycastDisabled = true } - // Labels: always visible on the current level (regardless of mode) - const showLabel = !!selectedLevelId && isOnSelectedLevel + // Labels: visible on the current level (regardless of mode), but never + // during snapshot capture. + const showLabel = !isCaptureMode && !!selectedLevelId && isOnSelectedLevel const labelOpacity = showLabel ? '1' : '0' const labelEl = document.getElementById(`${zoneId}-label`) if (labelEl && labelEl.style.opacity !== labelOpacity) { diff --git a/packages/editor/src/components/ui/action-menu/camera-actions.tsx b/packages/editor/src/components/ui/action-menu/camera-actions.tsx index 4a86fb7d8..6cf346501 100644 --- a/packages/editor/src/components/ui/action-menu/camera-actions.tsx +++ b/packages/editor/src/components/ui/action-menu/camera-actions.tsx @@ -33,7 +33,7 @@ export function CameraActions({ hideOrbit = false }: { hideOrbit?: boolean }) { alt="Orbit Left" className="h-[28px] w-[28px] -scale-x-100 object-contain opacity-70 transition-opacity group-hover:opacity-100" height={28} - src="/icons/rotate.png" + src="/icons/rotate.webp" width={28} /> @@ -50,7 +50,7 @@ export function CameraActions({ hideOrbit = false }: { hideOrbit?: boolean }) { alt="Orbit Right" className="h-[28px] w-[28px] object-contain opacity-70 transition-opacity group-hover:opacity-100" height={28} - src="/icons/rotate.png" + src="/icons/rotate.webp" width={28} /> @@ -69,7 +69,7 @@ export function CameraActions({ hideOrbit = false }: { hideOrbit?: boolean }) { alt="Top View" className="h-[28px] w-[28px] object-contain opacity-70 transition-opacity group-hover:opacity-100" height={28} - src="/icons/topview.png" + src="/icons/topview.webp" width={28} /> diff --git a/packages/editor/src/components/ui/action-menu/control-modes.tsx b/packages/editor/src/components/ui/action-menu/control-modes.tsx index 15fe4a173..ae1f51143 100644 --- a/packages/editor/src/components/ui/action-menu/control-modes.tsx +++ b/packages/editor/src/components/ui/action-menu/control-modes.tsx @@ -24,7 +24,7 @@ type ControlConfig = { const controls: ControlConfig[] = [ { id: 'select', - imageSrc: '/icons/select.png', + imageSrc: '/icons/select.webp', label: 'Select', shortcut: 'V', color: 'hover:bg-blue-500/20 hover:text-blue-400', @@ -32,7 +32,7 @@ const controls: ControlConfig[] = [ }, { id: 'zone', - imageSrc: '/icons/zone.png', + imageSrc: '/icons/zone.webp', label: 'Zone', shortcut: 'Z', color: 'hover:bg-green-500/20 hover:text-green-400', diff --git a/packages/editor/src/components/ui/action-menu/furnish-tools.tsx b/packages/editor/src/components/ui/action-menu/furnish-tools.tsx index da2c8dfb6..a3c629bdf 100644 --- a/packages/editor/src/components/ui/action-menu/furnish-tools.tsx +++ b/packages/editor/src/components/ui/action-menu/furnish-tools.tsx @@ -8,9 +8,9 @@ export type FurnishToolConfig = { } export const furnishTools: FurnishToolConfig[] = [ - { id: 'item', iconSrc: '/icons/couch.png', label: 'Furniture', catalogCategory: 'furniture' }, - { id: 'item', iconSrc: '/icons/appliance.png', label: 'Appliance', catalogCategory: 'appliance' }, - { id: 'item', iconSrc: '/icons/kitchen.png', label: 'Kitchen', catalogCategory: 'kitchen' }, - { id: 'item', iconSrc: '/icons/bathroom.png', label: 'Bathroom', catalogCategory: 'bathroom' }, - { id: 'item', iconSrc: '/icons/tree.png', label: 'Outdoor', catalogCategory: 'outdoor' }, + { id: 'item', iconSrc: '/icons/couch.webp', label: 'Furniture', catalogCategory: 'furniture' }, + { id: 'item', iconSrc: '/icons/appliance.webp', label: 'Appliance', catalogCategory: 'appliance' }, + { id: 'item', iconSrc: '/icons/kitchen.webp', label: 'Kitchen', catalogCategory: 'kitchen' }, + { id: 'item', iconSrc: '/icons/bathroom.webp', label: 'Bathroom', catalogCategory: 'bathroom' }, + { id: 'item', iconSrc: '/icons/tree.webp', label: 'Outdoor', catalogCategory: 'outdoor' }, ] diff --git a/packages/editor/src/components/ui/action-menu/structure-tools.tsx b/packages/editor/src/components/ui/action-menu/structure-tools.tsx index 4cc564255..c399afbac 100644 --- a/packages/editor/src/components/ui/action-menu/structure-tools.tsx +++ b/packages/editor/src/components/ui/action-menu/structure-tools.tsx @@ -12,26 +12,26 @@ export type ToolConfig = { // for cursor/floorplan indicators. Roof-mounted accessories are intentionally // absent — they're placed from the roof inspector's "Add element" section. export const tools: ToolConfig[] = [ - { id: 'wall', iconSrc: '/icons/wall.png', label: 'Wall' }, - { id: 'door', iconSrc: '/icons/door.png', label: 'Door' }, - { id: 'window', iconSrc: '/icons/window.png', label: 'Window' }, - { id: 'stair', iconSrc: '/icons/stairs.png', label: 'Stairs' }, - { id: 'roof', iconSrc: '/icons/roof.png', label: 'Gable Roof' }, - { id: 'fence', iconSrc: '/icons/fence.png', label: 'Fence' }, - { id: 'column', iconSrc: '/icons/column.png', label: 'Column' }, - { id: 'elevator', iconSrc: '/icons/elevator.png', label: 'Elevator' }, - { id: 'slab', iconSrc: '/icons/floor.png', label: 'Slab' }, - { id: 'ceiling', iconSrc: '/icons/ceiling.png', label: 'Ceiling' }, - { id: 'zone', iconSrc: '/icons/zone.png', label: 'Zone' }, - { id: 'spawn', iconSrc: '/icons/spawn-point.png', label: 'Spawn Point' }, - { id: 'shelf', iconSrc: '/icons/shelf.png', label: 'Shelf' }, - { id: 'duct-segment', iconSrc: '/icons/duct.png', label: 'Duct' }, - { id: 'duct-fitting', iconSrc: '/icons/duct-fitting.png', label: 'Duct Fitting' }, - { id: 'duct-terminal', iconSrc: '/icons/registers.png', label: 'Register' }, - { id: 'hvac-equipment', iconSrc: '/icons/HVAC.png', label: 'HVAC Unit' }, - { id: 'pipe-segment', iconSrc: '/icons/dwv-pipes.png', label: 'DWV Pipe' }, - { id: 'pipe-trap', iconSrc: '/icons/dwv-pipes.png', label: 'Trap' }, - { id: 'pipe-fitting', iconSrc: '/icons/duct-fitting.png', label: 'Pipe Fitting' }, - { id: 'lineset', iconSrc: '/icons/lineset.png', label: 'Lineset' }, - { id: 'liquid-line', iconSrc: '/icons/lineset.png', label: 'Liquid Line' }, + { id: 'wall', iconSrc: '/icons/wall.webp', label: 'Wall' }, + { id: 'door', iconSrc: '/icons/door.webp', label: 'Door' }, + { id: 'window', iconSrc: '/icons/window.webp', label: 'Window' }, + { id: 'stair', iconSrc: '/icons/stairs.webp', label: 'Stairs' }, + { id: 'roof', iconSrc: '/icons/roof.webp', label: 'Gable Roof' }, + { id: 'fence', iconSrc: '/icons/fence.webp', label: 'Fence' }, + { id: 'column', iconSrc: '/icons/column.webp', label: 'Column' }, + { id: 'elevator', iconSrc: '/icons/elevator.webp', label: 'Elevator' }, + { id: 'slab', iconSrc: '/icons/floor.webp', label: 'Slab' }, + { id: 'ceiling', iconSrc: '/icons/ceiling.webp', label: 'Ceiling' }, + { id: 'zone', iconSrc: '/icons/zone.webp', label: 'Zone' }, + { id: 'spawn', iconSrc: '/icons/spawn-point.webp', label: 'Spawn Point' }, + { id: 'shelf', iconSrc: '/icons/shelf.webp', label: 'Shelf' }, + { id: 'duct-segment', iconSrc: '/icons/duct.webp', label: 'Duct' }, + { id: 'duct-fitting', iconSrc: '/icons/duct-fitting.webp', label: 'Duct Fitting' }, + { id: 'duct-terminal', iconSrc: '/icons/registers.webp', label: 'Register' }, + { id: 'hvac-equipment', iconSrc: '/icons/HVAC.webp', label: 'HVAC Unit' }, + { id: 'pipe-segment', iconSrc: '/icons/dwv-pipes.webp', label: 'DWV Pipe' }, + { id: 'pipe-trap', iconSrc: '/icons/dwv-pipes.webp', label: 'Trap' }, + { id: 'pipe-fitting', iconSrc: '/icons/duct-fitting.webp', label: 'Pipe Fitting' }, + { id: 'lineset', iconSrc: '/icons/lineset.webp', label: 'Lineset' }, + { id: 'liquid-line', iconSrc: '/icons/lineset.webp', label: 'Liquid Line' }, ] diff --git a/packages/editor/src/components/ui/action-menu/view-toggles.tsx b/packages/editor/src/components/ui/action-menu/view-toggles.tsx index 93c456ec5..0d7b57dcb 100644 --- a/packages/editor/src/components/ui/action-menu/view-toggles.tsx +++ b/packages/editor/src/components/ui/action-menu/view-toggles.tsx @@ -226,7 +226,7 @@ function GuidesControl() { Guides {guides.length} @@ -265,7 +265,7 @@ function GuidesControl() {
- +

Guide images

@@ -305,7 +305,7 @@ function GuidesControl() {

{guide.name || `Guide image ${index + 1}`} @@ -466,7 +466,7 @@ function ScansControl() { variant="ghost" >

- Scans + Scans {scans.length} @@ -504,7 +504,7 @@ function ScansControl() {
- +

Scans

@@ -544,7 +544,7 @@ function ScansControl() {

{scan.name || `Scan ${index + 1}`} @@ -765,7 +765,7 @@ function ReferencesControl() { References {total} @@ -808,7 +808,7 @@ function ReferencesControl() { )} = { - item: { icon: '/icons/furniture.png', label: 'Item' }, - wall: { icon: '/icons/wall.png', label: 'Wall' }, - door: { icon: '/icons/door.png', label: 'Door' }, - window: { icon: '/icons/window.png', label: 'Window' }, - slab: { icon: '/icons/floor.png', label: 'Slab' }, - ceiling: { icon: '/icons/ceiling.png', label: 'Ceiling' }, - column: { icon: '/icons/column.png', label: 'Column' }, - elevator: { icon: '/icons/elevator.png', label: 'Elevator' }, - fence: { icon: '/icons/fence.png', label: 'Fence' }, - roof: { icon: '/icons/roof.png', label: 'Roof' }, - 'roof-segment': { icon: '/icons/roof.png', label: 'Roof segment' }, - stair: { icon: '/icons/stair.png', label: 'Stair' }, - 'stair-segment': { icon: '/icons/stair.png', label: 'Stair segment' }, - scan: { icon: '/icons/mesh.png', label: '3D Scan' }, - guide: { icon: '/icons/floorplan.png', label: 'Guide image' }, + item: { icon: '/icons/furniture.webp', label: 'Item' }, + wall: { icon: '/icons/wall.webp', label: 'Wall' }, + door: { icon: '/icons/door.webp', label: 'Door' }, + window: { icon: '/icons/window.webp', label: 'Window' }, + slab: { icon: '/icons/floor.webp', label: 'Slab' }, + ceiling: { icon: '/icons/ceiling.webp', label: 'Ceiling' }, + column: { icon: '/icons/column.webp', label: 'Column' }, + elevator: { icon: '/icons/elevator.webp', label: 'Elevator' }, + fence: { icon: '/icons/fence.webp', label: 'Fence' }, + roof: { icon: '/icons/roof.webp', label: 'Roof' }, + 'roof-segment': { icon: '/icons/roof.webp', label: 'Roof segment' }, + stair: { icon: '/icons/stair.webp', label: 'Stair' }, + 'stair-segment': { icon: '/icons/stair.webp', label: 'Stair segment' }, + scan: { icon: '/icons/mesh.webp', label: '3D Scan' }, + guide: { icon: '/icons/floorplan.webp', label: 'Guide image' }, } export function getNodeDisplay(node: AnyNode | null | undefined): NodeDisplay { - if (!node) return { icon: '/icons/select.png', label: 'Selection' } - const fallback = TYPE_DEFAULTS[node.type] ?? { icon: '/icons/select.png', label: node.type } + if (!node) return { icon: '/icons/select.webp', label: 'Selection' } + const fallback = TYPE_DEFAULTS[node.type] ?? { icon: '/icons/select.webp', label: node.type } // Item nodes carry an asset with its own thumbnail/name if (node.type === 'item') { return { diff --git a/packages/editor/src/components/ui/panels/panel-wrapper.tsx b/packages/editor/src/components/ui/panels/panel-wrapper.tsx index b4ae33441..91101d1aa 100644 --- a/packages/editor/src/components/ui/panels/panel-wrapper.tsx +++ b/packages/editor/src/components/ui/panels/panel-wrapper.tsx @@ -52,7 +52,7 @@ export const InspectorFooterContext = createContext(null) interface PanelWrapperProps { title: string - /** Either a URL path (legacy panels pass `/icons/floor.png` etc., + /** Either a URL path (legacy panels pass `/icons/floor.webp` etc., * rendered via next/image) OR a React node (registry-driven * inspector renders `` from * `def.presentation.icon`). */ diff --git a/packages/editor/src/components/ui/sidebar/icon-rail.tsx b/packages/editor/src/components/ui/sidebar/icon-rail.tsx index eb6d9eabc..9718fb552 100644 --- a/packages/editor/src/components/ui/sidebar/icon-rail.tsx +++ b/packages/editor/src/components/ui/sidebar/icon-rail.tsx @@ -22,13 +22,13 @@ interface IconRailProps { const sitePanel: { id: PanelId; iconSrc: string; label: string } = { id: 'site', - iconSrc: '/icons/level.png', + iconSrc: '/icons/level.webp', label: 'Site', } const settingsPanel: { id: PanelId; iconSrc: string; label: string } = { id: 'settings', - iconSrc: '/icons/settings.png', + iconSrc: '/icons/settings.webp', label: 'Settings', } diff --git a/packages/editor/src/components/ui/sidebar/panels/site-panel/ceiling-tree-node.tsx b/packages/editor/src/components/ui/sidebar/panels/site-panel/ceiling-tree-node.tsx index 576e48744..c71fa6edd 100644 --- a/packages/editor/src/components/ui/sidebar/panels/site-panel/ceiling-tree-node.tsx +++ b/packages/editor/src/components/ui/sidebar/panels/site-panel/ceiling-tree-node.tsx @@ -85,7 +85,7 @@ export const CeilingTreeNode = memo(function CeilingTreeNode({ expanded={expanded} hasChildren={children.length > 0} icon={ - + } isHovered={isHovered} isLast={isLast} diff --git a/packages/editor/src/components/ui/sidebar/panels/site-panel/chimney-tree-node.tsx b/packages/editor/src/components/ui/sidebar/panels/site-panel/chimney-tree-node.tsx index 408b8d693..764a50c12 100644 --- a/packages/editor/src/components/ui/sidebar/panels/site-panel/chimney-tree-node.tsx +++ b/packages/editor/src/components/ui/sidebar/panels/site-panel/chimney-tree-node.tsx @@ -57,7 +57,7 @@ export const ChimneyTreeNode = memo(function ChimneyTreeNode({ alt="" className="object-contain opacity-60" height={14} - src="/icons/roof.png" + src="/icons/roof.webp" width={14} /> diff --git a/packages/editor/src/components/ui/sidebar/panels/site-panel/column-tree-node.tsx b/packages/editor/src/components/ui/sidebar/panels/site-panel/column-tree-node.tsx index af37aaf16..230cc724d 100644 --- a/packages/editor/src/components/ui/sidebar/panels/site-panel/column-tree-node.tsx +++ b/packages/editor/src/components/ui/sidebar/panels/site-panel/column-tree-node.tsx @@ -51,7 +51,7 @@ export const ColumnTreeNode = memo(function ColumnTreeNode({ expanded={false} hasChildren={false} icon={ - + } isHovered={isHovered} isLast={isLast} diff --git a/packages/editor/src/components/ui/sidebar/panels/site-panel/door-tree-node.tsx b/packages/editor/src/components/ui/sidebar/panels/site-panel/door-tree-node.tsx index 60c9d5893..dd88e7fb5 100644 --- a/packages/editor/src/components/ui/sidebar/panels/site-panel/door-tree-node.tsx +++ b/packages/editor/src/components/ui/sidebar/panels/site-panel/door-tree-node.tsx @@ -57,7 +57,7 @@ export const DoorTreeNode = memo(function DoorTreeNode({ hasChildren={false} icon={ - + } isHovered={isHovered} diff --git a/packages/editor/src/components/ui/sidebar/panels/site-panel/dormer-tree-node.tsx b/packages/editor/src/components/ui/sidebar/panels/site-panel/dormer-tree-node.tsx index aadf0025d..3cc1f3542 100644 --- a/packages/editor/src/components/ui/sidebar/panels/site-panel/dormer-tree-node.tsx +++ b/packages/editor/src/components/ui/sidebar/panels/site-panel/dormer-tree-node.tsx @@ -63,7 +63,7 @@ export const DormerTreeNode = memo(function DormerTreeNode({ alt="" className="object-contain opacity-60" height={14} - src="/icons/roof.png" + src="/icons/roof.webp" width={14} /> diff --git a/packages/editor/src/components/ui/sidebar/panels/site-panel/elevator-tree-node.tsx b/packages/editor/src/components/ui/sidebar/panels/site-panel/elevator-tree-node.tsx index 085eb5ab1..80dc790c2 100644 --- a/packages/editor/src/components/ui/sidebar/panels/site-panel/elevator-tree-node.tsx +++ b/packages/editor/src/components/ui/sidebar/panels/site-panel/elevator-tree-node.tsx @@ -49,7 +49,7 @@ export const ElevatorTreeNode = memo(function ElevatorTreeNode({ expanded={false} hasChildren={false} icon={ - + } isHovered={isHovered} isLast={isLast} diff --git a/packages/editor/src/components/ui/sidebar/panels/site-panel/fence-tree-node.tsx b/packages/editor/src/components/ui/sidebar/panels/site-panel/fence-tree-node.tsx index c6635e831..86f5a7bef 100644 --- a/packages/editor/src/components/ui/sidebar/panels/site-panel/fence-tree-node.tsx +++ b/packages/editor/src/components/ui/sidebar/panels/site-panel/fence-tree-node.tsx @@ -43,7 +43,7 @@ export const FenceTreeNode = memo(function FenceTreeNode({ expanded={false} hasChildren={false} icon={ - + } isHovered={isHovered} isLast={isLast} diff --git a/packages/editor/src/components/ui/sidebar/panels/site-panel/gutter-tree-node.tsx b/packages/editor/src/components/ui/sidebar/panels/site-panel/gutter-tree-node.tsx index 64f8343b7..6e378b50b 100644 --- a/packages/editor/src/components/ui/sidebar/panels/site-panel/gutter-tree-node.tsx +++ b/packages/editor/src/components/ui/sidebar/panels/site-panel/gutter-tree-node.tsx @@ -57,7 +57,7 @@ export const GutterTreeNode = memo(function GutterTreeNode({ alt="" className="object-contain opacity-60" height={14} - src="/icons/roof.png" + src="/icons/roof.webp" width={14} /> diff --git a/packages/editor/src/components/ui/sidebar/panels/site-panel/index.tsx b/packages/editor/src/components/ui/sidebar/panels/site-panel/index.tsx index 7d02ab61e..bb5209eba 100644 --- a/packages/editor/src/components/ui/sidebar/panels/site-panel/index.tsx +++ b/packages/editor/src/components/ui/sidebar/panels/site-panel/index.tsx @@ -356,13 +356,13 @@ const ReferenceItem = memo(function ReferenceItem({ Scan ) : ( Guide )} Structure

@@ -1035,7 +1035,7 @@ const LayerToggle = memo(function LayerToggle() { 'mb-1 h-6 w-6 transition-all', activeTab !== 'furnish' && 'opacity-50 grayscale', )} - src="/icons/couch.png" + src="/icons/couch.webp" /> Furnish
@@ -1072,7 +1072,7 @@ const LayerToggle = memo(function LayerToggle() { 'mb-1 h-6 w-6 transition-all', activeTab !== 'zones' && 'opacity-50 grayscale', )} - src="/icons/kitchen.png" + src="/icons/kitchen.webp" /> Zones
@@ -1413,7 +1413,7 @@ const BuildingItem = memo(function BuildingItem({ 'h-5 w-5 object-contain transition-all', !isBuildingActive && 'opacity-60 grayscale', )} - src="/icons/building.png" + src="/icons/building.webp" /> {building.name || 'Building'}
@@ -1569,7 +1569,7 @@ export function SitePanel({ projectId, onUploadAsset, onDeleteAsset }: SitePanel 'h-5 w-5 object-contain transition-all', phase !== 'site' && 'opacity-60 grayscale', )} - src="/icons/site-flag.png" + src="/icons/site-flag.webp" /> {siteNode.name || 'Site'}
diff --git a/packages/editor/src/components/ui/sidebar/panels/site-panel/item-tree-node.tsx b/packages/editor/src/components/ui/sidebar/panels/site-panel/item-tree-node.tsx index 594623f8d..15b9704c9 100644 --- a/packages/editor/src/components/ui/sidebar/panels/site-panel/item-tree-node.tsx +++ b/packages/editor/src/components/ui/sidebar/panels/site-panel/item-tree-node.tsx @@ -15,13 +15,13 @@ import { import { TreeNodeActions } from './tree-node-actions' const CATEGORY_ICONS: Record = { - door: '/icons/door.png', - window: '/icons/window.png', - furniture: '/icons/couch.png', - appliance: '/icons/appliance.png', - kitchen: '/icons/kitchen.png', - bathroom: '/icons/bathroom.png', - outdoor: '/icons/tree.png', + door: '/icons/door.webp', + window: '/icons/window.webp', + furniture: '/icons/couch.webp', + appliance: '/icons/appliance.webp', + kitchen: '/icons/kitchen.webp', + bathroom: '/icons/bathroom.webp', + outdoor: '/icons/tree.webp', } interface ItemTreeNodeProps { @@ -88,7 +88,7 @@ export const ItemTreeNode = memo(function ItemTreeNode({ const handleStartEditing = useCallback(() => setIsEditing(true), []) const handleStopEditing = useCallback(() => setIsEditing(false), []) - const iconSrc = CATEGORY_ICONS[asset?.category ?? ''] || '/icons/couch.png' + const iconSrc = CATEGORY_ICONS[asset?.category ?? ''] || '/icons/couch.webp' const snapTarget = resolveNodeSnapTarget(node) const defaultName = asset?.name || 'Item' const hasChildren = children.length > 0 diff --git a/packages/editor/src/components/ui/sidebar/panels/site-panel/registry-tree-node.tsx b/packages/editor/src/components/ui/sidebar/panels/site-panel/registry-tree-node.tsx index 550decc7c..6e99e4da2 100644 --- a/packages/editor/src/components/ui/sidebar/panels/site-panel/registry-tree-node.tsx +++ b/packages/editor/src/components/ui/sidebar/panels/site-panel/registry-tree-node.tsx @@ -40,7 +40,7 @@ export const RegistryTreeNode = memo(function RegistryTreeNode({ const presentation = node ? nodeRegistry.get(node.type)?.presentation : undefined const icon = presentation?.icon - const iconSrc = icon?.kind === 'url' ? icon.src : '/icons/roof.png' + const iconSrc = icon?.kind === 'url' ? icon.src : '/icons/roof.webp' const snapTarget = resolveNodeSnapTarget(node) const defaultName = node?.name || presentation?.label || 'Node' diff --git a/packages/editor/src/components/ui/sidebar/panels/site-panel/roof-tree-node.tsx b/packages/editor/src/components/ui/sidebar/panels/site-panel/roof-tree-node.tsx index 78759be4e..eb23ca4d0 100644 --- a/packages/editor/src/components/ui/sidebar/panels/site-panel/roof-tree-node.tsx +++ b/packages/editor/src/components/ui/sidebar/panels/site-panel/roof-tree-node.tsx @@ -98,7 +98,7 @@ export const RoofTreeNode = memo(function RoofTreeNode({ expanded={expanded} hasChildren={segments.length > 0} icon={ - + } isDropTarget={isValidDropTarget && isDropTarget} isHovered={isHovered || isDropTarget} @@ -230,7 +230,7 @@ function RoofSegmentTreeNode({ alt="" className="object-contain opacity-60" height={14} - src="/icons/roof.png" + src="/icons/roof.webp" width={14} /> } diff --git a/packages/editor/src/components/ui/sidebar/panels/site-panel/shelf-tree-node.tsx b/packages/editor/src/components/ui/sidebar/panels/site-panel/shelf-tree-node.tsx index a54fc2b88..ffab4a760 100644 --- a/packages/editor/src/components/ui/sidebar/panels/site-panel/shelf-tree-node.tsx +++ b/packages/editor/src/components/ui/sidebar/panels/site-panel/shelf-tree-node.tsx @@ -96,7 +96,7 @@ export const ShelfTreeNode = memo(function ShelfTreeNode({ expanded={expanded} hasChildren={hasChildren} icon={ - + } isHovered={isHovered} isLast={isLast} diff --git a/packages/editor/src/components/ui/sidebar/panels/site-panel/slab-tree-node.tsx b/packages/editor/src/components/ui/sidebar/panels/site-panel/slab-tree-node.tsx index d26854cd8..627dc8dd9 100644 --- a/packages/editor/src/components/ui/sidebar/panels/site-panel/slab-tree-node.tsx +++ b/packages/editor/src/components/ui/sidebar/panels/site-panel/slab-tree-node.tsx @@ -55,7 +55,7 @@ export const SlabTreeNode = memo(function SlabTreeNode({ expanded={false} hasChildren={false} icon={ - + } isHovered={isHovered} isLast={isLast} diff --git a/packages/editor/src/components/ui/sidebar/panels/site-panel/solar-panel-tree-node.tsx b/packages/editor/src/components/ui/sidebar/panels/site-panel/solar-panel-tree-node.tsx index 088f683e2..3bde68860 100644 --- a/packages/editor/src/components/ui/sidebar/panels/site-panel/solar-panel-tree-node.tsx +++ b/packages/editor/src/components/ui/sidebar/panels/site-panel/solar-panel-tree-node.tsx @@ -57,7 +57,7 @@ export const SolarPanelTreeNode = memo(function SolarPanelTreeNode({ alt="" className="object-contain opacity-60" height={14} - src="/icons/roof.png" + src="/icons/roof.webp" width={14} /> diff --git a/packages/editor/src/components/ui/sidebar/panels/site-panel/spawn-tree-node.tsx b/packages/editor/src/components/ui/sidebar/panels/site-panel/spawn-tree-node.tsx index d973df1bb..118c92419 100644 --- a/packages/editor/src/components/ui/sidebar/panels/site-panel/spawn-tree-node.tsx +++ b/packages/editor/src/components/ui/sidebar/panels/site-panel/spawn-tree-node.tsx @@ -54,7 +54,7 @@ export const SpawnTreeNode = memo(function SpawnTreeNode({ alt="" className="object-contain" height={14} - src="/icons/spawn-point.png" + src="/icons/spawn-point.webp" width={14} /> } diff --git a/packages/editor/src/components/ui/sidebar/panels/site-panel/stair-tree-node.tsx b/packages/editor/src/components/ui/sidebar/panels/site-panel/stair-tree-node.tsx index 0a345c234..2f5114deb 100644 --- a/packages/editor/src/components/ui/sidebar/panels/site-panel/stair-tree-node.tsx +++ b/packages/editor/src/components/ui/sidebar/panels/site-panel/stair-tree-node.tsx @@ -98,7 +98,7 @@ export const StairTreeNode = memo(function StairTreeNode({ expanded={expanded} hasChildren={segments.length > 0} icon={ - + } isDropTarget={isValidDropTarget && isDropTarget} isHovered={isHovered || isDropTarget} @@ -206,7 +206,7 @@ function StairSegmentTreeNode({ alt="" className="object-contain opacity-60" height={14} - src="/icons/stairs.png" + src="/icons/stairs.webp" width={14} /> } diff --git a/packages/editor/src/components/ui/sidebar/panels/site-panel/wall-tree-node.tsx b/packages/editor/src/components/ui/sidebar/panels/site-panel/wall-tree-node.tsx index e040ccbae..2cdbe70ec 100644 --- a/packages/editor/src/components/ui/sidebar/panels/site-panel/wall-tree-node.tsx +++ b/packages/editor/src/components/ui/sidebar/panels/site-panel/wall-tree-node.tsx @@ -79,7 +79,7 @@ export const WallTreeNode = memo(function WallTreeNode({ expanded={expanded} hasChildren={children.length > 0} icon={ - + } isHovered={isHovered} isLast={isLast} diff --git a/packages/editor/src/components/ui/sidebar/panels/site-panel/window-tree-node.tsx b/packages/editor/src/components/ui/sidebar/panels/site-panel/window-tree-node.tsx index 1f16a1391..8e230e2ea 100644 --- a/packages/editor/src/components/ui/sidebar/panels/site-panel/window-tree-node.tsx +++ b/packages/editor/src/components/ui/sidebar/panels/site-panel/window-tree-node.tsx @@ -57,7 +57,7 @@ export const WindowTreeNode = memo(function WindowTreeNode({ hasChildren={false} icon={ - + } isHovered={isHovered} diff --git a/packages/editor/src/components/ui/snap-target-badge.tsx b/packages/editor/src/components/ui/snap-target-badge.tsx index a0ce4ac92..4c318cd93 100644 --- a/packages/editor/src/components/ui/snap-target-badge.tsx +++ b/packages/editor/src/components/ui/snap-target-badge.tsx @@ -6,9 +6,9 @@ export type SnapTarget = 'wall' | 'ceiling' | 'roof' export type SnapTargetBadgeSize = 'tile' | 'tree' const SNAP_TARGET_ICONS: Record = { - wall: '/icons/wall.png', - ceiling: '/icons/ceiling.png', - roof: '/icons/roof.png', + wall: '/icons/wall.webp', + ceiling: '/icons/ceiling.webp', + roof: '/icons/roof.webp', } const SNAP_TARGET_LABELS: Record = { diff --git a/packages/editor/src/components/viewer-overlay.tsx b/packages/editor/src/components/viewer-overlay.tsx index 28f5f8762..477f46f37 100644 --- a/packages/editor/src/components/viewer-overlay.tsx +++ b/packages/editor/src/components/viewer-overlay.tsx @@ -64,19 +64,19 @@ const levelModeBadgeLabels: Record<'manual' | 'stacked' | 'exploded' | 'solo', s const wallModeConfig = { up: { icon: (props: any) => ( - Full Height + Full Height ), label: 'Full Height', }, cutaway: { icon: (props: any) => ( - Cutaway + Cutaway ), label: 'Cutaway', }, down: { icon: (props: any) => ( - Low + Low ), label: 'Low', }, @@ -455,7 +455,7 @@ export const ViewerOverlay = ({ Scans )} @@ -476,7 +476,7 @@ export const ViewerOverlay = ({ Guides )} @@ -582,7 +582,7 @@ export const ViewerOverlay = ({ Orbit Left @@ -597,7 +597,7 @@ export const ViewerOverlay = ({ Orbit Right @@ -612,7 +612,7 @@ export const ViewerOverlay = ({ Top View
diff --git a/packages/editor/src/store/use-editor.tsx b/packages/editor/src/store/use-editor.tsx index 96337af45..19543f62f 100644 --- a/packages/editor/src/store/use-editor.tsx +++ b/packages/editor/src/store/use-editor.tsx @@ -688,6 +688,11 @@ export function selectSiteFloorplanContext() { }) } +// Stashes the view mode the user was in before entering capture, so we can +// restore it on exit. Snapshot capture always frames in 3D — the 2D/split +// floorplan panes render nothing meaningful for a thumbnail. +let viewModeBeforeCapture: ViewMode | null = null + const useEditor = create()( persist( (set, get) => ({ @@ -947,7 +952,35 @@ const useEditor = create()( setCaptureMode: (next) => { const resolved: CaptureMode = typeof next === 'boolean' ? { mode: next ? 'standard' : 'idle' } : next - set({ captureMode: resolved, isCaptureMode: resolved.mode !== 'idle' }) + const entering = resolved.mode !== 'idle' + set((state) => { + if (entering) { + // Force 3D for the shot. Remember the prior mode only on the first + // entry (viewMode is already '3d' on re-entry), so we restore the + // user's real choice — not the forced '3d' — when capture ends. + if (state.viewMode !== '3d') { + viewModeBeforeCapture = state.viewMode + return { + captureMode: resolved, + isCaptureMode: true, + viewMode: '3d', + isFloorplanOpen: false, + } + } + return { captureMode: resolved, isCaptureMode: true } + } + const restore = viewModeBeforeCapture + viewModeBeforeCapture = null + if (restore && restore !== '3d') { + return { + captureMode: resolved, + isCaptureMode: false, + viewMode: restore, + isFloorplanOpen: true, + } + } + return { captureMode: resolved, isCaptureMode: false } + }) }, viewMode: DEFAULT_PERSISTED_EDITOR_UI_STATE.viewMode, setViewMode: (mode) => set({ viewMode: mode, isFloorplanOpen: mode !== '3d' }), diff --git a/packages/nodes/src/box-vent/definition.ts b/packages/nodes/src/box-vent/definition.ts index ba67a52cd..f085a7d2e 100644 --- a/packages/nodes/src/box-vent/definition.ts +++ b/packages/nodes/src/box-vent/definition.ts @@ -220,7 +220,7 @@ export const boxVentDefinition: NodeDefinition = { presentation: { label: 'Box Vent', description: 'Small louvered exhaust vent that sits on a roof slope.', - icon: { kind: 'url', src: '/icons/roof.png' }, + icon: { kind: 'url', src: '/icons/roof.webp' }, paletteSection: 'structure', paletteOrder: 120, }, diff --git a/packages/nodes/src/box-vent/panel.tsx b/packages/nodes/src/box-vent/panel.tsx index aeacb39ee..1d89804e3 100644 --- a/packages/nodes/src/box-vent/panel.tsx +++ b/packages/nodes/src/box-vent/panel.tsx @@ -164,7 +164,7 @@ export default function BoxVentPanel() { return ( = { presentation: { label: 'Building', description: 'A building container holding one or more levels.', - icon: { kind: 'url', src: '/icons/building.png' }, + icon: { kind: 'url', src: '/icons/building.webp' }, paletteSection: 'site', paletteOrder: 6, }, diff --git a/packages/nodes/src/ceiling/definition.ts b/packages/nodes/src/ceiling/definition.ts index a59a70349..e716dc6a2 100644 --- a/packages/nodes/src/ceiling/definition.ts +++ b/packages/nodes/src/ceiling/definition.ts @@ -157,7 +157,7 @@ export const ceilingDefinition: NodeDefinition = { presentation: { label: 'Ceiling', description: 'A polygon-bounded ceiling surface that hosts ceiling-mounted items.', - icon: { kind: 'url', src: '/icons/ceiling.png' }, + icon: { kind: 'url', src: '/icons/ceiling.webp' }, paletteSection: 'structure', paletteOrder: 40, }, diff --git a/packages/nodes/src/ceiling/panel.tsx b/packages/nodes/src/ceiling/panel.tsx index 67eceeffe..ebbd3a668 100644 --- a/packages/nodes/src/ceiling/panel.tsx +++ b/packages/nodes/src/ceiling/panel.tsx @@ -147,7 +147,7 @@ export function CeilingPanel() { return ( = { presentation: { label: 'Chimney', description: 'Vertical masonry stack on a roof segment.', - icon: { kind: 'url', src: '/icons/roof.png' }, + icon: { kind: 'url', src: '/icons/roof.webp' }, paletteSection: 'structure', paletteOrder: 122, }, diff --git a/packages/nodes/src/chimney/panel.tsx b/packages/nodes/src/chimney/panel.tsx index 2f8e7a3f5..a01e7371c 100644 --- a/packages/nodes/src/chimney/panel.tsx +++ b/packages/nodes/src/chimney/panel.tsx @@ -339,7 +339,7 @@ export default function ChimneyPanel() { // Match the current store node against the preset table so the return ( = { presentation: { label: 'Column', description: 'A parametric column with configurable cross-section, base, and capital.', - icon: { kind: 'url', src: '/icons/column.png' }, + icon: { kind: 'url', src: '/icons/column.webp' }, paletteSection: 'structure', paletteOrder: 70, }, diff --git a/packages/nodes/src/column/panel.tsx b/packages/nodes/src/column/panel.tsx index c181b5ad3..b8329b8d6 100644 --- a/packages/nodes/src/column/panel.tsx +++ b/packages/nodes/src/column/panel.tsx @@ -313,7 +313,7 @@ export default function ColumnPanel() { return ( = { presentation: { label: 'Cupola', description: 'Louvered roof lantern with a dome or pyramid cap and optional finial.', - icon: { kind: 'url', src: '/icons/roof.png' }, + icon: { kind: 'url', src: '/icons/roof.webp' }, paletteSection: 'structure', paletteOrder: 122, }, diff --git a/packages/nodes/src/cupola/panel.tsx b/packages/nodes/src/cupola/panel.tsx index a3ecc88a4..ec6f68af0 100644 --- a/packages/nodes/src/cupola/panel.tsx +++ b/packages/nodes/src/cupola/panel.tsx @@ -137,7 +137,7 @@ export default function CupolaPanel() { return ( = { presentation: { label: 'Door', description: 'A door cut into a wall. Animated open/close state.', - icon: { kind: 'url', src: '/icons/door.png' }, + icon: { kind: 'url', src: '/icons/door.webp' }, paletteSection: 'structure', paletteOrder: 50, }, diff --git a/packages/nodes/src/door/panel.tsx b/packages/nodes/src/door/panel.tsx index e778743b0..c4a5f52f8 100644 --- a/packages/nodes/src/door/panel.tsx +++ b/packages/nodes/src/door/panel.tsx @@ -516,7 +516,7 @@ export default function DoorPanel() { return ( = { presentation: { label: 'Dormer', description: 'House-shaped protrusion on a roof segment.', - icon: { kind: 'url', src: '/icons/roof.png' }, + icon: { kind: 'url', src: '/icons/roof.webp' }, paletteSection: 'structure', paletteOrder: 125, }, diff --git a/packages/nodes/src/dormer/panel.tsx b/packages/nodes/src/dormer/panel.tsx index 7eff4733b..dd19c16df 100644 --- a/packages/nodes/src/dormer/panel.tsx +++ b/packages/nodes/src/dormer/panel.tsx @@ -159,7 +159,7 @@ export default function DormerPanel() { return ( = { presentation: { label: 'Downspout', description: 'Vertical drop pipe from a gutter outlet to the ground.', - icon: { kind: 'url', src: '/icons/roof.png' }, + icon: { kind: 'url', src: '/icons/roof.webp' }, paletteSection: 'structure', paletteOrder: 123, }, diff --git a/packages/nodes/src/duct-fitting/definition.ts b/packages/nodes/src/duct-fitting/definition.ts index 9b1cf316c..72a102d7c 100644 --- a/packages/nodes/src/duct-fitting/definition.ts +++ b/packages/nodes/src/duct-fitting/definition.ts @@ -122,7 +122,7 @@ export const ductFittingDefinition: NodeDefinition = { presentation: { label: 'Duct Fitting', description: 'Elbow, tee, reducer, or square-to-round transition connecting duct runs.', - icon: { kind: 'url', src: '/icons/duct-fitting.png' }, + icon: { kind: 'url', src: '/icons/duct-fitting.webp' }, paletteSection: 'structure', paletteOrder: 91, }, diff --git a/packages/nodes/src/duct-segment/definition.ts b/packages/nodes/src/duct-segment/definition.ts index 2f55db950..9c5e74af3 100644 --- a/packages/nodes/src/duct-segment/definition.ts +++ b/packages/nodes/src/duct-segment/definition.ts @@ -176,7 +176,7 @@ export const ductSegmentDefinition: NodeDefinition = { presentation: { label: 'Duct', description: 'HVAC duct run — polyline of round, rect, or flat-oval sections.', - icon: { kind: 'url', src: '/icons/duct.png' }, + icon: { kind: 'url', src: '/icons/duct.webp' }, paletteSection: 'structure', paletteOrder: 90, }, diff --git a/packages/nodes/src/duct-terminal/definition.ts b/packages/nodes/src/duct-terminal/definition.ts index b083017f1..4a9602682 100644 --- a/packages/nodes/src/duct-terminal/definition.ts +++ b/packages/nodes/src/duct-terminal/definition.ts @@ -89,7 +89,7 @@ export const ductTerminalDefinition: NodeDefinition = { label: 'Register', description: 'Duct terminal — supply register, ceiling diffuser, or return grille. Duct runs end at its collar.', - icon: { kind: 'url', src: '/icons/registers.png' }, + icon: { kind: 'url', src: '/icons/registers.webp' }, paletteSection: 'structure', paletteOrder: 93, }, diff --git a/packages/nodes/src/elevator/definition.ts b/packages/nodes/src/elevator/definition.ts index f72bd8a3c..c692cf395 100644 --- a/packages/nodes/src/elevator/definition.ts +++ b/packages/nodes/src/elevator/definition.ts @@ -256,7 +256,7 @@ export const elevatorDefinition: NodeDefinition = { presentation: { label: 'Elevator', description: 'A multi-level elevator shaft with configurable openings per level.', - icon: { kind: 'url', src: '/icons/wallcut.png' }, + icon: { kind: 'url', src: '/icons/wallcut.webp' }, paletteSection: 'structure', paletteOrder: 80, }, diff --git a/packages/nodes/src/elevator/panel.tsx b/packages/nodes/src/elevator/panel.tsx index 9eb51e3bf..09ac7cc9c 100644 --- a/packages/nodes/src/elevator/panel.tsx +++ b/packages/nodes/src/elevator/panel.tsx @@ -471,7 +471,7 @@ export default function ElevatorPanel() { return ( = { presentation: { label: 'Eyebrow Vent', description: 'Low curved lens-shaped roof vent with a louvered front.', - icon: { kind: 'url', src: '/icons/roof.png' }, + icon: { kind: 'url', src: '/icons/roof.webp' }, paletteSection: 'structure', paletteOrder: 123, }, diff --git a/packages/nodes/src/eyebrow-vent/panel.tsx b/packages/nodes/src/eyebrow-vent/panel.tsx index d43fd4b80..44934767d 100644 --- a/packages/nodes/src/eyebrow-vent/panel.tsx +++ b/packages/nodes/src/eyebrow-vent/panel.tsx @@ -139,7 +139,7 @@ export default function EyebrowVentPanel() { return ( = { presentation: { label: 'Fence', description: 'A straight or curved fence segment with configurable posts and infill.', - icon: { kind: 'url', src: '/icons/fence.png' }, + icon: { kind: 'url', src: '/icons/fence.webp' }, paletteSection: 'structure', paletteOrder: 20, }, diff --git a/packages/nodes/src/guide/definition.ts b/packages/nodes/src/guide/definition.ts index 2f5e09f5a..cd2c546b6 100644 --- a/packages/nodes/src/guide/definition.ts +++ b/packages/nodes/src/guide/definition.ts @@ -45,7 +45,7 @@ export const guideDefinition: NodeDefinition = { presentation: { label: 'Guide', description: 'A measurement / reference annotation (linear, area, or arc).', - icon: { kind: 'url', src: '/icons/blueprint.png' }, + icon: { kind: 'url', src: '/icons/blueprint.webp' }, paletteSection: 'site', paletteOrder: 30, }, diff --git a/packages/nodes/src/gutter/definition.ts b/packages/nodes/src/gutter/definition.ts index 2e6d655b6..f191dcbdd 100644 --- a/packages/nodes/src/gutter/definition.ts +++ b/packages/nodes/src/gutter/definition.ts @@ -181,7 +181,7 @@ export const gutterDefinition: NodeDefinition = { presentation: { label: 'Gutter', description: 'Rain-water channel running along the eave of a roof segment.', - icon: { kind: 'url', src: '/icons/roof.png' }, + icon: { kind: 'url', src: '/icons/roof.webp' }, paletteSection: 'structure', paletteOrder: 122, }, diff --git a/packages/nodes/src/hvac-equipment/definition.ts b/packages/nodes/src/hvac-equipment/definition.ts index 6daa77afd..47921bd9d 100644 --- a/packages/nodes/src/hvac-equipment/definition.ts +++ b/packages/nodes/src/hvac-equipment/definition.ts @@ -94,7 +94,7 @@ export const hvacEquipmentDefinition: NodeDefinition = label: 'HVAC Unit', description: 'Furnace, air handler, or condenser — duct runs connect to its supply/return collars.', - icon: { kind: 'url', src: '/icons/HVAC.png' }, + icon: { kind: 'url', src: '/icons/HVAC.webp' }, paletteSection: 'structure', paletteOrder: 92, }, diff --git a/packages/nodes/src/item/definition.ts b/packages/nodes/src/item/definition.ts index 9224d701f..115727d17 100644 --- a/packages/nodes/src/item/definition.ts +++ b/packages/nodes/src/item/definition.ts @@ -320,7 +320,7 @@ export const itemDefinition: NodeDefinition = { presentation: { label: 'Item', description: 'A catalog-backed item (furniture, fixtures, decorations).', - icon: { kind: 'url', src: '/icons/item.png' }, + icon: { kind: 'url', src: '/icons/item.webp' }, paletteSection: 'furnish', paletteOrder: 10, }, diff --git a/packages/nodes/src/item/panel.tsx b/packages/nodes/src/item/panel.tsx index d484410f8..1ef946f42 100644 --- a/packages/nodes/src/item/panel.tsx +++ b/packages/nodes/src/item/panel.tsx @@ -100,7 +100,7 @@ export default function ItemPanel() { return ( = { presentation: { label: 'Level', description: 'A single floor of a building, holding walls / slabs / ceilings / items.', - icon: { kind: 'url', src: '/icons/level.png' }, + icon: { kind: 'url', src: '/icons/level.webp' }, paletteSection: 'site', paletteOrder: 7, }, diff --git a/packages/nodes/src/lineset/definition.ts b/packages/nodes/src/lineset/definition.ts index e08370025..03e40495f 100644 --- a/packages/nodes/src/lineset/definition.ts +++ b/packages/nodes/src/lineset/definition.ts @@ -120,7 +120,7 @@ export const linesetDefinition: NodeDefinition = { label: 'Lineset', description: 'Refrigerant lineset — copper suction + liquid pair joining a condenser to the indoor coil.', - icon: { kind: 'url', src: '/icons/lineset.png' }, + icon: { kind: 'url', src: '/icons/lineset.webp' }, paletteSection: 'structure', paletteOrder: 93, }, diff --git a/packages/nodes/src/liquid-line/definition.ts b/packages/nodes/src/liquid-line/definition.ts index 97cbc80a4..87a0cc693 100644 --- a/packages/nodes/src/liquid-line/definition.ts +++ b/packages/nodes/src/liquid-line/definition.ts @@ -112,7 +112,7 @@ export const liquidLineDefinition: NodeDefinition = { label: 'Liquid Line', description: 'Standalone refrigerant liquid line — a thin bare-copper run; Follow mode traces an existing lineset.', - icon: { kind: 'url', src: '/icons/lineset.png' }, + icon: { kind: 'url', src: '/icons/lineset.webp' }, paletteSection: 'structure', paletteOrder: 94, }, diff --git a/packages/nodes/src/pipe-fitting/definition.ts b/packages/nodes/src/pipe-fitting/definition.ts index 3c533cda8..b00ffb924 100644 --- a/packages/nodes/src/pipe-fitting/definition.ts +++ b/packages/nodes/src/pipe-fitting/definition.ts @@ -93,7 +93,7 @@ export const pipeFittingDefinition: NodeDefinition = { label: 'Pipe Fitting', description: 'DWV joint — elbow bend, 45° wye, or sanitary tee.', // Reuses the duct-fitting artwork — DWV fittings read the same in the UI. - icon: { kind: 'url', src: '/icons/duct-fitting.png' }, + icon: { kind: 'url', src: '/icons/duct-fitting.webp' }, paletteSection: 'structure', paletteOrder: 96, hidden: true, diff --git a/packages/nodes/src/pipe-segment/definition.ts b/packages/nodes/src/pipe-segment/definition.ts index 6ac636c64..ce2800559 100644 --- a/packages/nodes/src/pipe-segment/definition.ts +++ b/packages/nodes/src/pipe-segment/definition.ts @@ -118,7 +118,7 @@ export const pipeSegmentDefinition: NodeDefinition = { label: 'DWV Pipe', description: 'Drain / waste / vent pipe run — waste lines fall at ¼″ per foot, vents run level or vertical.', - icon: { kind: 'url', src: '/icons/dwv-pipes.png' }, + icon: { kind: 'url', src: '/icons/dwv-pipes.webp' }, paletteSection: 'structure', paletteOrder: 95, }, diff --git a/packages/nodes/src/ridge-vent/definition.ts b/packages/nodes/src/ridge-vent/definition.ts index ec702f5f4..9d11c8632 100644 --- a/packages/nodes/src/ridge-vent/definition.ts +++ b/packages/nodes/src/ridge-vent/definition.ts @@ -205,7 +205,7 @@ export const ridgeVentDefinition: NodeDefinition = { presentation: { label: 'Ridge Vent', description: 'Ventilation strip running along the ridge of a roof segment.', - icon: { kind: 'url', src: '/icons/roof.png' }, + icon: { kind: 'url', src: '/icons/roof.webp' }, paletteSection: 'structure', paletteOrder: 121, }, diff --git a/packages/nodes/src/ridge-vent/panel.tsx b/packages/nodes/src/ridge-vent/panel.tsx index dd0f2e7cc..957c77952 100644 --- a/packages/nodes/src/ridge-vent/panel.tsx +++ b/packages/nodes/src/ridge-vent/panel.tsx @@ -128,7 +128,7 @@ export default function RidgeVentPanel() { return ( = { presentation: { label: 'Roof Segment', description: 'A single pitched plane of a parent roof.', - icon: { kind: 'url', src: '/icons/roof.png' }, + icon: { kind: 'url', src: '/icons/roof.webp' }, paletteSection: 'structure', paletteOrder: 101, }, diff --git a/packages/nodes/src/roof-segment/panel.tsx b/packages/nodes/src/roof-segment/panel.tsx index 9a8a7ddbb..907f55fb9 100644 --- a/packages/nodes/src/roof-segment/panel.tsx +++ b/packages/nodes/src/roof-segment/panel.tsx @@ -121,7 +121,7 @@ export default function RoofSegmentPanel() { return ( = { presentation: { label: 'Roof', description: 'A pitched / hip / gable roof composed of one or more segments.', - icon: { kind: 'url', src: '/icons/roof.png' }, + icon: { kind: 'url', src: '/icons/roof.webp' }, paletteSection: 'structure', paletteOrder: 100, }, diff --git a/packages/nodes/src/roof/panel.tsx b/packages/nodes/src/roof/panel.tsx index 094926c12..6424af86d 100644 --- a/packages/nodes/src/roof/panel.tsx +++ b/packages/nodes/src/roof/panel.tsx @@ -249,7 +249,7 @@ export default function RoofPanel() { return ( = { presentation: { label: 'Scan', description: 'A captured mesh (LiDAR / photogrammetry) imported as a scene reference.', - icon: { kind: 'url', src: '/icons/mesh.png' }, + icon: { kind: 'url', src: '/icons/mesh.webp' }, paletteSection: 'site', paletteOrder: 40, }, diff --git a/packages/nodes/src/shelf/definition.ts b/packages/nodes/src/shelf/definition.ts index bcb97f04d..d42bd14f7 100644 --- a/packages/nodes/src/shelf/definition.ts +++ b/packages/nodes/src/shelf/definition.ts @@ -265,7 +265,7 @@ export const shelfDefinition: NodeDefinition = { presentation: { label: 'Shelf', description: 'A configurable shelving unit. Items host on each row.', - icon: { kind: 'url', src: '/icons/shelf.png' }, + icon: { kind: 'url', src: '/icons/shelf.webp' }, paletteSection: 'furnish', paletteOrder: 30, }, diff --git a/packages/nodes/src/site/definition.ts b/packages/nodes/src/site/definition.ts index 512d92164..c944325cb 100644 --- a/packages/nodes/src/site/definition.ts +++ b/packages/nodes/src/site/definition.ts @@ -41,7 +41,7 @@ export const siteDefinition: NodeDefinition = { presentation: { label: 'Site', description: 'The top-level container holding buildings, zones, and the property boundary.', - icon: { kind: 'url', src: '/icons/site-flag.png' }, + icon: { kind: 'url', src: '/icons/site-flag.webp' }, paletteSection: 'site', paletteOrder: 5, }, diff --git a/packages/nodes/src/skylight/definition.ts b/packages/nodes/src/skylight/definition.ts index a32a3f7e7..fa7161fbb 100644 --- a/packages/nodes/src/skylight/definition.ts +++ b/packages/nodes/src/skylight/definition.ts @@ -271,7 +271,7 @@ export const skylightDefinition: NodeDefinition = { presentation: { label: 'Skylight', description: 'Framed glass opening on a roof segment.', - icon: { kind: 'url', src: '/icons/roof.png' }, + icon: { kind: 'url', src: '/icons/roof.webp' }, paletteSection: 'structure', paletteOrder: 124, }, diff --git a/packages/nodes/src/skylight/panel.tsx b/packages/nodes/src/skylight/panel.tsx index ed4d90d0f..2eaba0cb5 100644 --- a/packages/nodes/src/skylight/panel.tsx +++ b/packages/nodes/src/skylight/panel.tsx @@ -258,7 +258,7 @@ export default function SkylightPanel() { return ( = { presentation: { label: 'Slab', description: 'A polygon-bounded floor surface that hosts items on top.', - icon: { kind: 'url', src: '/icons/floor.png' }, + icon: { kind: 'url', src: '/icons/floor.webp' }, paletteSection: 'structure', paletteOrder: 30, }, diff --git a/packages/nodes/src/slab/panel.tsx b/packages/nodes/src/slab/panel.tsx index fca302c22..fcbd60038 100644 --- a/packages/nodes/src/slab/panel.tsx +++ b/packages/nodes/src/slab/panel.tsx @@ -152,7 +152,7 @@ export function SlabPanel() { return ( = { presentation: { label: 'Solar Panel', description: 'Grid of photovoltaic panels mounted on a roof segment.', - icon: { kind: 'url', src: '/icons/roof.png' }, + icon: { kind: 'url', src: '/icons/roof.webp' }, paletteSection: 'structure', paletteOrder: 123, }, diff --git a/packages/nodes/src/solar-panel/panel.tsx b/packages/nodes/src/solar-panel/panel.tsx index 099510cc2..92351bc1b 100644 --- a/packages/nodes/src/solar-panel/panel.tsx +++ b/packages/nodes/src/solar-panel/panel.tsx @@ -181,7 +181,7 @@ export default function SolarPanelPanel() { return ( = { presentation: { label: 'Spawn Point', description: 'Player or camera origin within a level. One per level.', - icon: { kind: 'url', src: '/icons/spawn-point.png' }, + icon: { kind: 'url', src: '/icons/spawn-point.webp' }, paletteSection: 'structure', paletteOrder: 90, // bottom of structure list — matches legacy palette order }, diff --git a/packages/nodes/src/spawn/panel.tsx b/packages/nodes/src/spawn/panel.tsx index e8a29302b..de8e49d09 100644 --- a/packages/nodes/src/spawn/panel.tsx +++ b/packages/nodes/src/spawn/panel.tsx @@ -95,7 +95,7 @@ export default function SpawnPanel() { return ( = { presentation: { label: 'Stair Segment', description: 'A single flight of a parent stair.', - icon: { kind: 'url', src: '/icons/stairs.png' }, + icon: { kind: 'url', src: '/icons/stairs.webp' }, paletteSection: 'structure', paletteOrder: 111, }, diff --git a/packages/nodes/src/stair-segment/panel.tsx b/packages/nodes/src/stair-segment/panel.tsx index 792675519..af6c71011 100644 --- a/packages/nodes/src/stair-segment/panel.tsx +++ b/packages/nodes/src/stair-segment/panel.tsx @@ -121,7 +121,7 @@ export default function StairSegmentPanel() { return ( = { label: 'Stair', description: 'A stair composed of one or more flights with configurable treads, risers, railings.', - icon: { kind: 'url', src: '/icons/stairs.png' }, + icon: { kind: 'url', src: '/icons/stairs.webp' }, paletteSection: 'structure', paletteOrder: 110, }, diff --git a/packages/nodes/src/stair/panel.tsx b/packages/nodes/src/stair/panel.tsx index 1b9f2b92d..13d6e6f21 100644 --- a/packages/nodes/src/stair/panel.tsx +++ b/packages/nodes/src/stair/panel.tsx @@ -226,7 +226,7 @@ export default function StairPanel() { return ( = { presentation: { label: 'Turbine Vent', description: 'Wind-driven spinning whirlybird exhaust vent for a roof slope.', - icon: { kind: 'url', src: '/icons/roof.png' }, + icon: { kind: 'url', src: '/icons/roof.webp' }, paletteSection: 'structure', paletteOrder: 121, }, diff --git a/packages/nodes/src/turbine-vent/panel.tsx b/packages/nodes/src/turbine-vent/panel.tsx index 57898e925..9588668a9 100644 --- a/packages/nodes/src/turbine-vent/panel.tsx +++ b/packages/nodes/src/turbine-vent/panel.tsx @@ -161,7 +161,7 @@ export default function TurbineVentPanel() { return ( = { presentation: { label: 'Wall', description: 'A straight or curved wall segment. Hosts doors, windows, and wall-mounted items.', - icon: { kind: 'url', src: '/icons/wall.png' }, + icon: { kind: 'url', src: '/icons/wall.webp' }, paletteSection: 'structure', paletteOrder: 10, }, diff --git a/packages/nodes/src/wall/panel.tsx b/packages/nodes/src/wall/panel.tsx index 5750eefb2..31f495198 100644 --- a/packages/nodes/src/wall/panel.tsx +++ b/packages/nodes/src/wall/panel.tsx @@ -137,7 +137,7 @@ export default function WallPanel() { return ( = { presentation: { label: 'Window', description: 'A window cut into a wall. Animated open/close for opening windows.', - icon: { kind: 'url', src: '/icons/window.png' }, + icon: { kind: 'url', src: '/icons/window.webp' }, paletteSection: 'structure', paletteOrder: 60, }, diff --git a/packages/nodes/src/window/panel.tsx b/packages/nodes/src/window/panel.tsx index b1bd3b8fb..a1abde0fe 100644 --- a/packages/nodes/src/window/panel.tsx +++ b/packages/nodes/src/window/panel.tsx @@ -383,7 +383,7 @@ export default function WindowPanel() { return ( = { presentation: { label: 'Zone', description: 'A polygonal site zone (lawn, water, paving) with a TSL gradient material.', - icon: { kind: 'url', src: '/icons/zone.png' }, + icon: { kind: 'url', src: '/icons/zone.webp' }, paletteSection: 'site', paletteOrder: 20, },