diff --git a/src/components/custom-edge/CustomEdgeWrapper.tsx b/src/components/custom-edge/CustomEdgeWrapper.tsx
index a9f83b38..a1a8295b 100644
--- a/src/components/custom-edge/CustomEdgeWrapper.tsx
+++ b/src/components/custom-edge/CustomEdgeWrapper.tsx
@@ -425,7 +425,7 @@ export function CustomEdgeWrapper({
onDoubleClick={(e) => { e.stopPropagation(); beginLabelEdit(); }}
className={
visualQualityV2Enabled
- ? `px-2 py-0.5 rounded-full border shadow-sm text-[11px] font-medium select-none flow-lod-secondary flow-lod-shadow transition-all ${cinematicActive ? 'bg-white/96 border-slate-200/90 text-slate-600 shadow-[0_6px_18px_rgba(15,23,42,0.08)]' : 'bg-white/90 border-slate-200 text-slate-500 hover:border-indigo-300 hover:text-slate-700 hover:shadow active:ring-2 active:ring-indigo-400'}`
+ ? `whitespace-nowrap px-2 py-0.5 rounded-full border shadow-sm text-[11px] font-medium select-none flow-lod-secondary flow-lod-shadow transition-all ${cinematicActive ? 'bg-white/96 border-slate-200/90 text-slate-600 shadow-[0_6px_18px_rgba(15,23,42,0.08)]' : 'bg-white/90 border-slate-200 text-slate-500 hover:border-indigo-300 hover:text-slate-700 hover:shadow active:ring-2 active:ring-indigo-400'}`
: 'bg-white px-2 py-0.5 rounded border border-slate-200 shadow-sm text-[11px] font-medium text-slate-500 hover:ring-2 hover:ring-indigo-500/20 active:ring-indigo-500 select-none flow-lod-secondary flow-lod-shadow'
}
>
diff --git a/src/components/export/CinematicExportSurface.tsx b/src/components/export/CinematicExportSurface.tsx
deleted file mode 100644
index b603d9d7..00000000
--- a/src/components/export/CinematicExportSurface.tsx
+++ /dev/null
@@ -1,78 +0,0 @@
-import React, { forwardRef } from 'react';
-import { Background, BackgroundVariant, ReactFlow, ReactFlowProvider } from '@/lib/reactflowCompat';
-import type { FlowEdge, FlowNode } from '@/lib/types';
-import { useCinematicExportSurfaceConfig } from '@/context/CinematicExportContext';
-import { flowCanvasEdgeTypes, flowCanvasNodeTypes } from '@/components/flow-canvas/flowCanvasTypes';
-
-const CINEMATIC_EXPORT_SURFACE_BACKGROUND =
- 'radial-gradient(circle at top, rgba(59,130,246,0.14), transparent 42%), linear-gradient(180deg, #f8fbff 0%, #eef5ff 52%, #f8fafc 100%)';
-const CINEMATIC_EXPORT_SURFACE_STYLE = {
- position: 'fixed',
- top: 0,
- left: 0,
- transform: 'translate(-20000px, 0)',
- overflow: 'hidden',
- pointerEvents: 'none',
- zIndex: -1,
- background: CINEMATIC_EXPORT_SURFACE_BACKGROUND,
-} as const;
-
-interface CinematicExportSurfaceProps {
- nodes: FlowNode[];
- edges: FlowEdge[];
-}
-
-function CinematicExportSurfaceInner(
- { nodes, edges }: CinematicExportSurfaceProps,
- ref: React.ForwardedRef
,
-): React.ReactElement | null {
- const surfaceConfig = useCinematicExportSurfaceConfig();
-
- if (!surfaceConfig) {
- return null;
- }
-
- return (
-
-
-
-
-
-
-
- );
-}
-
-export const CinematicExportSurface = forwardRef(CinematicExportSurfaceInner);
-CinematicExportSurface.displayName = 'CinematicExportSurface';
diff --git a/src/components/flow-editor/useFlowEditorScreenModel.ts b/src/components/flow-editor/useFlowEditorScreenModel.ts
index fc7f177b..53f032de 100644
--- a/src/components/flow-editor/useFlowEditorScreenModel.ts
+++ b/src/components/flow-editor/useFlowEditorScreenModel.ts
@@ -90,7 +90,7 @@ export function useFlowEditorScreenModel({ onGoHome }: UseFlowEditorScreenModelP
onFileImport,
} = useFlowExport(screenState.recordHistory, screenState.reactFlowWrapper, {
stopPlayback,
- }, screenState.cinematicExportSurfaceRef);
+ });
const {
collaborationTopNavState,
@@ -309,7 +309,6 @@ export function useFlowEditorScreenModel({ onGoHome }: UseFlowEditorScreenModelP
recordHistory: screenState.recordHistory,
isSelectMode: screenState.isSelectMode,
reactFlowWrapper: screenState.reactFlowWrapper,
- cinematicExportSurfaceRef: screenState.cinematicExportSurfaceRef,
fileInputRef,
onFileImport,
shareViewerUrl,
diff --git a/src/components/flow-editor/useFlowEditorScreenState.ts b/src/components/flow-editor/useFlowEditorScreenState.ts
index 255db3fe..92c6dbe1 100644
--- a/src/components/flow-editor/useFlowEditorScreenState.ts
+++ b/src/components/flow-editor/useFlowEditorScreenState.ts
@@ -41,7 +41,6 @@ export function useFlowEditorScreenState() {
const snapshotsState = useSnapshots();
const uiState = useFlowEditorUIState();
const reactFlowWrapper = useRef(null);
- const cinematicExportSurfaceRef = useRef(null);
const reactFlowState = useReactFlow();
const historyState = useFlowHistory();
@@ -60,7 +59,6 @@ export function useFlowEditorScreenState() {
...snapshotsState,
...uiState,
reactFlowWrapper,
- cinematicExportSurfaceRef,
...reactFlowState,
...historyState,
};
diff --git a/src/components/home/HomeSidebar.tsx b/src/components/home/HomeSidebar.tsx
index 94b82d8a..d216a815 100644
--- a/src/components/home/HomeSidebar.tsx
+++ b/src/components/home/HomeSidebar.tsx
@@ -20,9 +20,7 @@ export function HomeSidebar({
return (
-
-
-
+
{APP_NAME}
diff --git a/src/components/icons/OpenFlowLogo.tsx b/src/components/icons/OpenFlowLogo.tsx
index f2ca0c92..68753d02 100644
--- a/src/components/icons/OpenFlowLogo.tsx
+++ b/src/components/icons/OpenFlowLogo.tsx
@@ -1,19 +1,14 @@
import React from 'react';
-export const OpenFlowLogo: React.FC<{ className?: string }> = ({ className }) => {
+const LOGO_SRC = '/favicon.svg';
+
+export const OpenFlowLogo: React.FC<{ className?: string }> = ({ className = '' }) => {
return (
-
-
-
+
);
};
diff --git a/src/components/top-nav/TopNavBrand.tsx b/src/components/top-nav/TopNavBrand.tsx
index ee45c180..d08467fe 100644
--- a/src/components/top-nav/TopNavBrand.tsx
+++ b/src/components/top-nav/TopNavBrand.tsx
@@ -22,11 +22,11 @@ export function TopNavBrand({ appName, logoUrl, logoStyle, ui }: TopNavBrandProp
return (
{(logoStyle === 'icon' || logoStyle === 'both') && (
-
+
{logoUrl ? (
-
+
) : (
-
+
)}
)}
@@ -43,8 +43,8 @@ export function TopNavBrand({ appName, logoUrl, logoStyle, ui }: TopNavBrandProp
) : (
-
-
+
+
{t('nav.wideLogo', 'Your Wide Logo')}
diff --git a/src/context/CinematicExportContext.tsx b/src/context/CinematicExportContext.tsx
index 2fc9a3bc..caddb3d2 100644
--- a/src/context/CinematicExportContext.tsx
+++ b/src/context/CinematicExportContext.tsx
@@ -18,24 +18,15 @@ function createInactiveRenderState(): CinematicRenderState {
};
}
-export interface CinematicExportSurfaceConfig {
- width: number;
- height: number;
-}
-
interface CinematicExportContextValue {
renderState: CinematicRenderState;
- surfaceConfig: CinematicExportSurfaceConfig | null;
setRenderState: (nextState: CinematicRenderState) => void;
- setSurfaceConfig: (nextConfig: CinematicExportSurfaceConfig | null) => void;
resetRenderState: () => void;
}
const INACTIVE_CONTEXT_VALUE: CinematicExportContextValue = {
renderState: createInactiveRenderState(),
- surfaceConfig: null,
setRenderState: () => undefined,
- setSurfaceConfig: () => undefined,
resetRenderState: () => undefined,
};
@@ -43,18 +34,14 @@ const CinematicExportContext = createContext
(INACTI
export function CinematicExportProvider({ children }: { children: React.ReactNode }): React.ReactElement {
const [renderState, setRenderStateState] = useState(() => createInactiveRenderState());
- const [surfaceConfig, setSurfaceConfigState] = useState(null);
const value = useMemo(() => ({
renderState,
- surfaceConfig,
setRenderState: (nextState) => setRenderStateState(nextState),
- setSurfaceConfig: (nextConfig) => setSurfaceConfigState(nextConfig),
resetRenderState: () => {
setRenderStateState(createInactiveRenderState());
- setSurfaceConfigState(null);
},
- }), [renderState, surfaceConfig]);
+ }), [renderState]);
return (
@@ -71,15 +58,10 @@ export function useCinematicExportState(): CinematicRenderState {
return useCinematicExportContext().renderState;
}
-export function useCinematicExportSurfaceConfig(): CinematicExportSurfaceConfig | null {
- return useCinematicExportContext().surfaceConfig;
-}
-
-export function useCinematicExportActions(): Pick {
- const { setRenderState, setSurfaceConfig, resetRenderState } = useCinematicExportContext();
+export function useCinematicExportActions(): Pick {
+ const { setRenderState, resetRenderState } = useCinematicExportContext();
return {
setRenderState,
- setSurfaceConfig,
resetRenderState,
};
}
diff --git a/src/hooks/flow-export/exportCapture.test.ts b/src/hooks/flow-export/exportCapture.test.ts
new file mode 100644
index 00000000..edd805d7
--- /dev/null
+++ b/src/hooks/flow-export/exportCapture.test.ts
@@ -0,0 +1,47 @@
+import { describe, expect, it, vi } from 'vitest';
+import { renderDecodedFrame } from './exportCapture';
+
+function createMockContext() {
+ return {
+ fillStyle: '',
+ fillRect: vi.fn(),
+ clearRect: vi.fn(),
+ drawImage: vi.fn(),
+ } as unknown as CanvasRenderingContext2D;
+}
+
+describe('renderDecodedFrame', () => {
+ it('clears the frame when no background is provided', () => {
+ const context = createMockContext();
+ const image = {} as CanvasImageSource;
+
+ renderDecodedFrame(context, 640, 360, image);
+
+ expect(context.clearRect).toHaveBeenCalledWith(0, 0, 640, 360);
+ expect(context.drawImage).toHaveBeenCalledWith(image, 0, 0, 640, 360);
+ });
+
+ it('fills a solid background when a background color is provided', () => {
+ const context = createMockContext();
+ const image = {} as CanvasImageSource;
+
+ renderDecodedFrame(context, 800, 600, image, '#ffffff');
+
+ expect(context.fillStyle).toBe('#ffffff');
+ expect(context.fillRect).toHaveBeenCalledWith(0, 0, 800, 600);
+ expect(context.clearRect).not.toHaveBeenCalled();
+ });
+
+ it('prefers a custom background painter over transparent compositing', () => {
+ const context = createMockContext();
+ const image = {} as CanvasImageSource;
+ const backgroundPainter = vi.fn();
+
+ renderDecodedFrame(context, 960, 540, image, '#ffffff', backgroundPainter);
+
+ expect(backgroundPainter).toHaveBeenCalledWith(context, 960, 540);
+ expect(context.fillRect).not.toHaveBeenCalled();
+ expect(context.clearRect).not.toHaveBeenCalled();
+ expect(context.drawImage).toHaveBeenCalledWith(image, 0, 0, 960, 540);
+ });
+});
diff --git a/src/hooks/flow-export/exportCapture.ts b/src/hooks/flow-export/exportCapture.ts
index 0f0efdba..348d1533 100644
--- a/src/hooks/flow-export/exportCapture.ts
+++ b/src/hooks/flow-export/exportCapture.ts
@@ -1,4 +1,3 @@
-import type React from 'react';
import { getCompatibleNodesBounds } from '@/lib/reactflowCompat';
import type { FlowNode } from '@/lib/types';
import { encodeGif } from '@/services/gifEncoder';
@@ -20,6 +19,12 @@ export interface DecodedFrame {
image: CanvasImageSource;
}
+export type FrameBackgroundPainter = (
+ context: CanvasRenderingContext2D,
+ width: number,
+ height: number,
+) => void;
+
export interface ExportCaptureOptions {
width: number;
height: number;
@@ -69,21 +74,6 @@ export async function waitForExportRender(minDelayMs = 0): Promise {
await waitForAnimationFrame();
}
-export async function waitForExportSurface(
- surfaceRef: React.RefObject | undefined,
- attempts = 8,
-): Promise {
- for (let attempt = 0; attempt < attempts; attempt += 1) {
- if (surfaceRef?.current) {
- return surfaceRef.current;
- }
-
- await waitForExportRender(8);
- }
-
- return surfaceRef?.current ?? null;
-}
-
export function createDownload(blob: Blob, fileName: string): void {
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
@@ -192,14 +182,17 @@ function createExportCanvas(width: number, height: number): {
return { canvas, context };
}
-function renderDecodedFrame(
+export function renderDecodedFrame(
context: CanvasRenderingContext2D,
width: number,
height: number,
image: CanvasImageSource,
backgroundColor?: string,
+ backgroundPainter?: FrameBackgroundPainter,
): void {
- if (backgroundColor) {
+ if (backgroundPainter) {
+ backgroundPainter(context, width, height);
+ } else if (backgroundColor) {
context.fillStyle = backgroundColor;
context.fillRect(0, 0, width, height);
} else {
@@ -214,13 +207,14 @@ export async function encodeGifFromFrames(params: {
width: number;
height: number;
backgroundColor?: string;
+ backgroundPainter?: FrameBackgroundPainter;
}): Promise {
- const { frames, width, height, backgroundColor } = params;
+ const { frames, width, height, backgroundColor, backgroundPainter } = params;
const { context } = createExportCanvas(width, height);
const gifFrames = [];
for (const { frame, image } of frames) {
- renderDecodedFrame(context, width, height, image, backgroundColor);
+ renderDecodedFrame(context, width, height, image, backgroundColor, backgroundPainter);
gifFrames.push({
imageData: context.getImageData(0, 0, width, height),
delayMs: frame.delayMs,
@@ -237,8 +231,9 @@ export async function encodeVideoFromFrames(params: {
fps: number;
mimeType: string;
backgroundColor?: string;
+ backgroundPainter?: FrameBackgroundPainter;
}): Promise {
- const { frames, width, height, fps, mimeType, backgroundColor } = params;
+ const { frames, width, height, fps, mimeType, backgroundColor, backgroundPainter } = params;
const { canvas, context } = createExportCanvas(width, height);
const stream = canvas.captureStream(fps);
const recorder = new MediaRecorder(stream, { mimeType });
@@ -260,7 +255,7 @@ export async function encodeVideoFromFrames(params: {
for (const { frame, image } of frames) {
const repeatCount = Math.max(1, Math.round(frame.delayMs / frameDurationMs));
for (let repeatIndex = 0; repeatIndex < repeatCount; repeatIndex += 1) {
- renderDecodedFrame(context, width, height, image, backgroundColor);
+ renderDecodedFrame(context, width, height, image, backgroundColor, backgroundPainter);
await wait(frameDurationMs);
}
}
diff --git a/src/hooks/useFlowExport.ts b/src/hooks/useFlowExport.ts
index b5852a1a..be05ad90 100644
--- a/src/hooks/useFlowExport.ts
+++ b/src/hooks/useFlowExport.ts
@@ -10,6 +10,10 @@ import { useViewSettings } from '@/store/viewHooks';
import { getAnimatedExportFileExtension, selectSupportedVideoMimeType } from '@/services/animatedExport';
import { buildCinematicBuildPlan, type CinematicExportKind } from '@/services/export/cinematicBuildPlan';
import { buildCinematicTimeline, getCinematicExportPreset, resolveCinematicRenderState } from '@/services/export/cinematicRenderState';
+import {
+ CINEMATIC_EXPORT_FALLBACK_COLOR,
+ paintCinematicExportBackground,
+} from '@/services/export/cinematicExportTheme';
import { useToast } from '../components/ui/ToastContext';
import { resolveFlowExportViewport } from './flowExportViewport';
import { notifyOperationOutcome } from '@/services/operationFeedback';
@@ -23,7 +27,6 @@ import {
encodeGifFromFrames,
encodeVideoFromFrames,
waitForExportRender,
- waitForExportSurface,
} from './flow-export/exportCapture';
import {
buildDiagramDocumentJson,
@@ -40,7 +43,6 @@ export const useFlowExport = (
recordHistory: () => void,
reactFlowWrapper: React.RefObject,
animatedPlayback: AnimatedPlaybackControls,
- cinematicExportSurfaceRef?: React.RefObject,
) => {
const tabs = useFlowStore((state) => state.tabs);
const { nodes, edges } = useCanvasState();
@@ -49,7 +51,7 @@ export const useFlowExport = (
const activeTabId = useActiveTabId();
const { updateTab } = useTabActions();
const { fitView } = useReactFlow();
- const { setRenderState, setSurfaceConfig, resetRenderState } = useCinematicExportActions();
+ const { setRenderState, resetRenderState } = useCinematicExportActions();
const { addToast } = useToast();
const fileInputRef = useRef(null);
const activeTab = tabs.find((tab) => tab.id === activeTabId);
@@ -216,6 +218,12 @@ export const useFlowExport = (
return;
}
+ const { viewport: flowViewport, message } = resolveFlowExportViewport(reactFlowWrapper.current);
+ if (!flowViewport) {
+ addToast(message ?? 'The canvas viewport could not be found.', 'error');
+ return;
+ }
+
if (nodes.length === 0) {
addToast('Add nodes before exporting a cinematic build animation.', 'error');
return;
@@ -247,41 +255,27 @@ export const useFlowExport = (
animatedPlayback.stopPlayback();
- setSurfaceConfig({
- width: frameOptions.width ?? 0,
- height: frameOptions.height ?? 0,
- });
- const exportSurfaceTarget = await waitForExportSurface(cinematicExportSurfaceRef);
-
- if (!exportSurfaceTarget) {
- throw new Error('Cinematic export surface is unavailable.');
- }
+ const captureCinematicFrame = async (): Promise => (
+ toPng(flowViewport, {
+ ...frameOptions,
+ backgroundColor: CINEMATIC_EXPORT_FALLBACK_COLOR,
+ cacheBust: true,
+ })
+ );
for (let timeMs = 0; timeMs < timeline.totalDurationMs; timeMs += frameDurationMs) {
setRenderState(resolveCinematicRenderState(timeline, edges, timeMs));
await waitForExportRender(12);
- const dataUrl = await toPng(exportSurfaceTarget, {
- backgroundColor: null,
- width: frameOptions.width,
- height: frameOptions.height,
- pixelRatio: frameOptions.pixelRatio,
- skipFonts: true,
- cacheBust: true,
+ capturedFrames.push({
+ dataUrl: await captureCinematicFrame(),
+ delayMs: frameDurationMs,
});
- capturedFrames.push({ dataUrl, delayMs: frameDurationMs });
}
setRenderState(resolveCinematicRenderState(timeline, edges, timeline.totalDurationMs));
await waitForExportRender(12);
capturedFrames.push({
- dataUrl: await toPng(exportSurfaceTarget, {
- backgroundColor: null,
- width: frameOptions.width,
- height: frameOptions.height,
- pixelRatio: frameOptions.pixelRatio,
- skipFonts: true,
- cacheBust: true,
- }),
+ dataUrl: await captureCinematicFrame(),
delayMs: Math.max(frameDurationMs, timeline.preset.finalHoldMs),
});
@@ -295,6 +289,7 @@ export const useFlowExport = (
frames: decodedFrames,
width,
height,
+ backgroundPainter: paintCinematicExportBackground,
});
createDownload(blob, buildExportFileName(exportBaseName ?? 'openflowkit-cinematic-build', 'gif'));
addToast('Cinematic build GIF exported.', 'success');
@@ -313,6 +308,7 @@ export const useFlowExport = (
height,
fps: timeline.preset.fps,
mimeType,
+ backgroundPainter: paintCinematicExportBackground,
});
const extension = getAnimatedExportFileExtension(mimeType);
createDownload(blob, buildExportFileName(exportBaseName ?? 'openflowkit-cinematic-build', extension));
@@ -325,7 +321,7 @@ export const useFlowExport = (
resetRenderState();
reactFlowWrapper.current?.classList.remove('exporting');
}
- }, [addToast, animatedPlayback, cinematicExportSurfaceRef, edges, exportBaseName, nodes, reactFlowWrapper, resetRenderState, setRenderState, setSurfaceConfig]);
+ }, [addToast, animatedPlayback, edges, exportBaseName, nodes, reactFlowWrapper, resetRenderState, setRenderState]);
// --- JSON Export ---
const handleExportJSON = useCallback(() => {
diff --git a/src/i18n/locales/en/translation.json b/src/i18n/locales/en/translation.json
index e86239ec..0c4630d9 100644
--- a/src/i18n/locales/en/translation.json
+++ b/src/i18n/locales/en/translation.json
@@ -387,7 +387,7 @@
"exportFormats": "Export to SVG, PNG, JPG",
"figmaExport": "Figma Export",
"mermaidSupport": "Mermaid.js Support",
- "aiGeneration": "AI diagram generation (bring your own API key)"
+ "aiGeneration": "AI diagram generation (BYOK)"
},
"supportDevelopment": "Support development on GitHub"
},
@@ -1211,4 +1211,4 @@
"closeTab": "Close Tab",
"newFlowTab": "New Flow Tab"
}
-}
+}
\ No newline at end of file
diff --git a/src/services/export/cinematicExportTheme.test.ts b/src/services/export/cinematicExportTheme.test.ts
new file mode 100644
index 00000000..9907c5f2
--- /dev/null
+++ b/src/services/export/cinematicExportTheme.test.ts
@@ -0,0 +1,38 @@
+import { describe, expect, it, vi } from 'vitest';
+import {
+ CINEMATIC_EXPORT_FALLBACK_COLOR,
+ CINEMATIC_EXPORT_SURFACE_BACKGROUND,
+ paintCinematicExportBackground,
+} from './cinematicExportTheme';
+
+function createGradient() {
+ return {
+ addColorStop: vi.fn(),
+ } as unknown as CanvasGradient;
+}
+
+describe('cinematicExportTheme', () => {
+ it('exposes a stable fallback background color', () => {
+ expect(CINEMATIC_EXPORT_FALLBACK_COLOR).toBe('#f8fbff');
+ expect(CINEMATIC_EXPORT_SURFACE_BACKGROUND).toContain('linear-gradient');
+ });
+
+ it('paints the cinematic background with layered gradients', () => {
+ const linearGradient = createGradient();
+ const radialGradient = createGradient();
+ const context = {
+ fillStyle: '',
+ fillRect: vi.fn(),
+ createLinearGradient: vi.fn(() => linearGradient),
+ createRadialGradient: vi.fn(() => radialGradient),
+ };
+
+ paintCinematicExportBackground(context, 1200, 630);
+
+ expect(context.createLinearGradient).toHaveBeenCalledWith(0, 0, 0, 630);
+ expect(context.createRadialGradient).toHaveBeenCalled();
+ expect(linearGradient.addColorStop).toHaveBeenCalledTimes(3);
+ expect(radialGradient.addColorStop).toHaveBeenCalledTimes(2);
+ expect(context.fillRect).toHaveBeenCalledTimes(2);
+ });
+});
diff --git a/src/services/export/cinematicExportTheme.ts b/src/services/export/cinematicExportTheme.ts
new file mode 100644
index 00000000..f75f32ad
--- /dev/null
+++ b/src/services/export/cinematicExportTheme.ts
@@ -0,0 +1,44 @@
+export const CINEMATIC_EXPORT_SURFACE_BACKGROUND =
+ 'radial-gradient(circle at top, rgba(59,130,246,0.14), transparent 42%), linear-gradient(180deg, #f8fbff 0%, #eef5ff 52%, #f8fafc 100%)';
+
+export const CINEMATIC_EXPORT_FALLBACK_COLOR = '#f8fbff';
+
+export interface BackgroundPaintContext {
+ fillStyle: string | CanvasGradient | CanvasPattern;
+ fillRect: (x: number, y: number, width: number, height: number) => void;
+ createLinearGradient: (x0: number, y0: number, x1: number, y1: number) => CanvasGradient;
+ createRadialGradient: (
+ x0: number,
+ y0: number,
+ r0: number,
+ x1: number,
+ y1: number,
+ r1: number,
+ ) => CanvasGradient;
+}
+
+export function paintCinematicExportBackground(
+ context: BackgroundPaintContext,
+ width: number,
+ height: number,
+): void {
+ const linearGradient = context.createLinearGradient(0, 0, 0, height);
+ linearGradient.addColorStop(0, '#f8fbff');
+ linearGradient.addColorStop(0.52, '#eef5ff');
+ linearGradient.addColorStop(1, '#f8fafc');
+ context.fillStyle = linearGradient;
+ context.fillRect(0, 0, width, height);
+
+ const radialGradient = context.createRadialGradient(
+ width * 0.5,
+ 0,
+ Math.max(1, width * 0.04),
+ width * 0.5,
+ 0,
+ Math.max(width, height) * 0.42,
+ );
+ radialGradient.addColorStop(0, 'rgba(59,130,246,0.14)');
+ radialGradient.addColorStop(1, 'rgba(59,130,246,0)');
+ context.fillStyle = radialGradient;
+ context.fillRect(0, 0, width, height);
+}
diff --git a/tsconfig.tsbuildinfo b/tsconfig.tsbuildinfo
index d8b108e0..4e84e22b 100644
--- a/tsconfig.tsbuildinfo
+++ b/tsconfig.tsbuildinfo
@@ -1 +1 @@
-{"root":["./src/app.tsx","./src/constants.test.ts","./src/constants.ts","./src/index.tsx","./src/store.test.ts","./src/store.ts","./src/theme.ts","./src/app/routestate.test.ts","./src/app/routestate.ts","./src/components/annotationnode.tsx","./src/components/commandbar.test.tsx","./src/components/commandbar.tsx","./src/components/connectmenu.test.tsx","./src/components/connectmenu.tsx","./src/components/contextmenu.tsx","./src/components/customconnectionline.tsx","./src/components/customedge.tsx","./src/components/customnode.handleinteraction.test.tsx","./src/components/customnode.tsx","./src/components/designsystem.integration.test.tsx","./src/components/diagramviewer.tsx","./src/components/errorboundary.tsx","./src/components/exportmenu.tsx","./src/components/exportmenupanel.test.tsx","./src/components/exportmenupanel.tsx","./src/components/flowcanvas.tsx","./src/components/floweditor.tsx","./src/components/floweditoremptystate.tsx","./src/components/floweditorlayoutoverlay.tsx","./src/components/floweditorpanels.test.tsx","./src/components/floweditorpanels.tsx","./src/components/flowtabs.tsx","./src/components/groupnode.tsx","./src/components/homepage.integration.test.tsx","./src/components/homepage.tsx","./src/components/iconmap.test.tsx","./src/components/iconmap.ts","./src/components/imagenode.tsx","./src/components/inlinetexteditsurface.test.tsx","./src/components/inlinetexteditsurface.tsx","./src/components/keyboardshortcutsmodal.tsx","./src/components/languageselector.tsx","./src/components/markdownrenderer.tsx","./src/components/memoizedmarkdown.tsx","./src/components/navigationcontrols.tsx","./src/components/nodechrome.tsx","./src/components/nodequickcreatebuttons.tsx","./src/components/nodetransformcontrols.tsx","./src/components/playbackcontrols.tsx","./src/components/propertiespanel.tsx","./src/components/rightrail.tsx","./src/components/sectionnode.tsx","./src/components/shareembedmodal.tsx","./src/components/sharemodal.test.tsx","./src/components/sharemodal.tsx","./src/components/sidebarshell.tsx","./src/components/snapshotspanel.tsx","./src/components/studioaipanel.test.tsx","./src/components/studioaipanel.tsx","./src/components/studiocodepanel.test.tsx","./src/components/studiocodepanel.tsx","./src/components/studiopanel.test.tsx","./src/components/studiopanel.tsx","./src/components/studioplaybackpanel.test.tsx","./src/components/studioplaybackpanel.tsx","./src/components/swimlanenode.tsx","./src/components/textnode.tsx","./src/components/toolbar.tsx","./src/components/tooltip.tsx","./src/components/topnav.tsx","./src/components/welcomemodal.tsx","./src/components/annotationtheme.ts","./src/components/container-nodes.handleinteraction.test.tsx","./src/components/editorsurfacetiers.ts","./src/components/handleinteraction.test.ts","./src/components/handleinteraction.ts","./src/components/handleinteractionusage.test.ts","./src/components/lightweight-nodes.handleinteraction.test.tsx","./src/components/markdownsyntax.ts","./src/components/sharemodalcontent.ts","./src/components/studioaicopy.ts","./src/components/transformdiagnostics.test.ts","./src/components/transformdiagnostics.ts","./src/components/useactivenodeselection.ts","./src/components/useexportmenu.ts","./src/components/settingsmodal/aisettings.tsx","./src/components/settingsmodal/generalsettings.tsx","./src/components/settingsmodal/privacysettings.tsx","./src/components/settingsmodal/settingsmodal.test.tsx","./src/components/settingsmodal/settingsmodal.tsx","./src/components/settingsmodal/shortcutssettings.tsx","./src/components/settingsmodal/ai/advancedendpointsection.tsx","./src/components/settingsmodal/ai/customheaderseditor.tsx","./src/components/settingsmodal/ai/privacysection.tsx","./src/components/settingsmodal/ai/providericon.tsx","./src/components/settingsmodal/ai/providersection.tsx","./src/components/settingsmodal/ai/step.tsx","./src/components/app/docssiteredirect.test.tsx","./src/components/app/docssiteredirect.tsx","./src/components/app/mobileworkspacegate.test.tsx","./src/components/app/mobileworkspacegate.tsx","./src/components/app/routeloadingfallback.test.tsx","./src/components/app/routeloadingfallback.tsx","./src/components/app/mobileworkspacegatecopy.ts","./src/components/app/routeloadingcopy.ts","./src/components/architecture-lint/lintrulespanel.tsx","./src/components/command-bar/assetsview.test.tsx","./src/components/command-bar/assetsview.tsx","./src/components/command-bar/designsystemeditor.tsx","./src/components/command-bar/designsystemview.tsx","./src/components/command-bar/figmaimportpanel.tsx","./src/components/command-bar/importview.tsx","./src/components/command-bar/layersview.tsx","./src/components/command-bar/layoutview.tsx","./src/components/command-bar/pagesview.tsx","./src/components/command-bar/rootview.test.tsx","./src/components/command-bar/rootview.tsx","./src/components/command-bar/searchview.tsx","./src/components/command-bar/templatesview.tsx","./src/components/command-bar/viewheader.tsx","./src/components/command-bar/visualsview.tsx","./src/components/command-bar/applycodechanges.ts","./src/components/command-bar/assetsviewconstants.ts","./src/components/command-bar/searchquery.test.ts","./src/components/command-bar/searchquery.ts","./src/components/command-bar/types.ts","./src/components/command-bar/useaiviewstate.test.tsx","./src/components/command-bar/useaiviewstate.ts","./src/components/command-bar/usecloudassetcatalog.ts","./src/components/command-bar/usecommandbarcommands.test.tsx","./src/components/command-bar/usecommandbarcommands.tsx","./src/components/custom-edge/customedgewrapper.tsx","./src/components/custom-edge/sequencemessageedge.test.tsx","./src/components/custom-edge/sequencemessageedge.tsx","./src/components/custom-edge/animatededgepresentation.test.ts","./src/components/custom-edge/animatededgepresentation.ts","./src/components/custom-edge/classrelationsemantics.test.ts","./src/components/custom-edge/classrelationsemantics.ts","./src/components/custom-edge/edgerendermode.ts","./src/components/custom-edge/pathutils.test.ts","./src/components/custom-edge/pathutils.ts","./src/components/custom-edge/pathutilsgeometry.ts","./src/components/custom-edge/pathutilssiblingrouting.ts","./src/components/custom-edge/pathutilstypes.ts","./src/components/custom-edge/relationroutingsemantics.test.ts","./src/components/custom-edge/relationroutingsemantics.ts","./src/components/custom-edge/standardedgemarkers.test.ts","./src/components/custom-edge/standardedgemarkers.ts","./src/components/custom-nodes/architecturenode.handleinteraction.test.tsx","./src/components/custom-nodes/architecturenode.tsx","./src/components/custom-nodes/browsernode.tsx","./src/components/custom-nodes/classentitynode.handleinteraction.test.tsx","./src/components/custom-nodes/classnode.tsx","./src/components/custom-nodes/entitynode.tsx","./src/components/custom-nodes/journeynode.tsx","./src/components/custom-nodes/mindmapnode.tsx","./src/components/custom-nodes/mobilenode.tsx","./src/components/custom-nodes/sequenceparticipantnode.tsx","./src/components/custom-nodes/structurednodehandles.tsx","./src/components/custom-nodes/visualnodes.handleinteraction.test.tsx","./src/components/custom-nodes/browservariantrenderer.tsx","./src/components/custom-nodes/mobilevariantrenderer.tsx","./src/components/custom-nodes/structuredlistnavigation.test.ts","./src/components/custom-nodes/structuredlistnavigation.ts","./src/components/diagram-diff/diffmodebanner.tsx","./src/components/export/cinematicexportsurface.tsx","./src/components/flow-canvas/flowcanvasalignmentguidesoverlay.tsx","./src/components/flow-canvas/flowcanvasoverlays.tsx","./src/components/flow-canvas/alignmentguides.test.ts","./src/components/flow-canvas/alignmentguides.ts","./src/components/flow-canvas/flowcanvasreactflowcontracts.ts","./src/components/flow-canvas/flowcanvastypes.test.ts","./src/components/flow-canvas/flowcanvastypes.tsx","./src/components/flow-canvas/largegraphsafetymode.test.ts","./src/components/flow-canvas/largegraphsafetymode.ts","./src/components/flow-canvas/nodechromecoverage.test.ts","./src/components/flow-canvas/pastehelpers.test.ts","./src/components/flow-canvas/pastehelpers.ts","./src/components/flow-canvas/useflowcanvasalignmentguides.ts","./src/components/flow-canvas/useflowcanvasconnectionstate.ts","./src/components/flow-canvas/useflowcanvascontextactions.ts","./src/components/flow-canvas/useflowcanvasdragdrop.ts","./src/components/flow-canvas/useflowcanvasinteractionlod.ts","./src/components/flow-canvas/useflowcanvasmenus.ts","./src/components/flow-canvas/useflowcanvasmenusandactions.test.tsx","./src/components/flow-canvas/useflowcanvasmenusandactions.ts","./src/components/flow-canvas/useflowcanvasnodedraghandlers.ts","./src/components/flow-canvas/useflowcanvaspaste.ts","./src/components/flow-canvas/useflowcanvasreactflowconfig.test.ts","./src/components/flow-canvas/useflowcanvasreactflowconfig.ts","./src/components/flow-canvas/useflowcanvasselectiontools.test.tsx","./src/components/flow-canvas/useflowcanvasselectiontools.ts","./src/components/flow-canvas/useflowcanvasviewstate.test.ts","./src/components/flow-canvas/useflowcanvasviewstate.ts","./src/components/flow-canvas/useflowcanvaszoomlod.ts","./src/components/flow-editor/collaborationpresenceoverlay.test.tsx","./src/components/flow-editor/collaborationpresenceoverlay.tsx","./src/components/flow-editor/floweditorchrome.tsx","./src/components/flow-editor/buildfloweditorcontrollerparams.ts","./src/components/flow-editor/buildfloweditorscreencontrollerparams.ts","./src/components/flow-editor/floweditorchromeprops.ts","./src/components/flow-editor/infradslapply.test.ts","./src/components/flow-editor/infradslapply.ts","./src/components/flow-editor/panelprops.test.ts","./src/components/flow-editor/panelprops.ts","./src/components/flow-editor/shouldexitstudioonselection.test.ts","./src/components/flow-editor/shouldexitstudioonselection.ts","./src/components/flow-editor/usecollaborationnodepositions.ts","./src/components/flow-editor/usefloweditorcontroller.ts","./src/components/flow-editor/usefloweditorinteractionbindings.ts","./src/components/flow-editor/usefloweditorpanelactions.ts","./src/components/flow-editor/usefloweditorpanelprops.ts","./src/components/flow-editor/usefloweditorruntime.ts","./src/components/flow-editor/usefloweditorscreenbehavior.ts","./src/components/flow-editor/usefloweditorscreenmodel.ts","./src/components/flow-editor/usefloweditorscreenstate.ts","./src/components/flow-editor/usefloweditorshellcontroller.test.tsx","./src/components/flow-editor/usefloweditorshellcontroller.ts","./src/components/flow-editor/usefloweditorstudiocontroller.test.tsx","./src/components/flow-editor/usefloweditorstudiocontroller.ts","./src/components/flow-editor/useinfradslapply.ts","./src/components/home/homedashboard.tsx","./src/components/home/homeflowdialogs.tsx","./src/components/home/homesettingsview.tsx","./src/components/home/homesidebar.tsx","./src/components/home/welcomemodalstate.ts","./src/components/icons/assetsicon.tsx","./src/components/icons/openflowlogo.tsx","./src/components/infra-sync/infrasyncpanel.test.tsx","./src/components/infra-sync/infrasyncpanel.tsx","./src/components/journey/journeyscorecontrol.test.tsx","./src/components/journey/journeyscorecontrol.tsx","./src/components/properties/bulknodeproperties.tsx","./src/components/properties/colorpicker.test.tsx","./src/components/properties/colorpicker.tsx","./src/components/properties/customcolorpopover.tsx","./src/components/properties/diagramnodepropertiesrouter.test.ts","./src/components/properties/diagramnodepropertiesrouter.tsx","./src/components/properties/edgeproperties.tsx","./src/components/properties/iconpicker.tsx","./src/components/properties/icontilepickerprimitives.tsx","./src/components/properties/imageupload.tsx","./src/components/properties/inspectorprimitives.tsx","./src/components/properties/nodeactionbuttons.tsx","./src/components/properties/nodecontentsection.tsx","./src/components/properties/nodeimagesettingssection.tsx","./src/components/properties/nodeproperties.tsx","./src/components/properties/nodetextstylesection.tsx","./src/components/properties/nodewireframevariantsection.tsx","./src/components/properties/propertysliderrow.tsx","./src/components/properties/segmentedchoice.tsx","./src/components/properties/shapeselector.tsx","./src/components/properties/swatchpicker.tsx","./src/components/properties/colorpickerutils.ts","./src/components/properties/propertyinputbehavior.test.ts","./src/components/properties/propertyinputbehavior.ts","./src/components/properties/wireframevariants.ts","./src/components/properties/edge/architectureedgesemanticssection.tsx","./src/components/properties/edge/edgecolorsection.tsx","./src/components/properties/edge/edgeconditionsection.tsx","./src/components/properties/edge/edgelabelsection.tsx","./src/components/properties/edge/edgerelationsection.test.tsx","./src/components/properties/edge/edgerelationsection.tsx","./src/components/properties/edge/edgeroutesection.test.tsx","./src/components/properties/edge/edgeroutesection.tsx","./src/components/properties/edge/edgestylesection.tsx","./src/components/properties/edge/sequencemessagesection.tsx","./src/components/properties/edge/architecturesemantics.test.ts","./src/components/properties/edge/architecturesemantics.ts","./src/components/properties/edge/edgelabelmodel.test.ts","./src/components/properties/edge/edgelabelmodel.ts","./src/components/properties/edge/errelationoptions.ts","./src/components/properties/families/architecturenodeproperties.test.tsx","./src/components/properties/families/architecturenodeproperties.tsx","./src/components/properties/families/architecturenodesection.tsx","./src/components/properties/families/classdiagramnodeproperties.tsx","./src/components/properties/families/classmemberlisteditor.tsx","./src/components/properties/families/classnodesection.tsx","./src/components/properties/families/erdiagramnodeproperties.tsx","./src/components/properties/families/entityfieldlisteditor.tsx","./src/components/properties/families/entitynodesection.tsx","./src/components/properties/families/journeynodeproperties.tsx","./src/components/properties/families/journeynodesection.tsx","./src/components/properties/families/mindmapnodeproperties.test.tsx","./src/components/properties/families/mindmapnodeproperties.tsx","./src/components/properties/families/sequencenodeproperties.tsx","./src/components/properties/families/sequencenodesection.tsx","./src/components/properties/families/structuredtextlisteditor.tsx","./src/components/studio-code-panel/usestudiocodepanelcontroller.test.tsx","./src/components/studio-code-panel/usestudiocodepanelcontroller.ts","./src/components/toolbar/toolbaraddmenu.tsx","./src/components/toolbar/toolbaraddmenupanel.tsx","./src/components/toolbar/toolbarhistorycontrols.tsx","./src/components/toolbar/toolbarmodecontrols.tsx","./src/components/toolbar/toolbarbuttonstyles.ts","./src/components/top-nav/topnavactions.tsx","./src/components/top-nav/topnavbrand.tsx","./src/components/top-nav/topnavmenu.test.tsx","./src/components/top-nav/topnavmenu.tsx","./src/components/top-nav/topnavmenupanel.tsx","./src/components/top-nav/usetopnavstate.ts","./src/components/ui/button.tsx","./src/components/ui/collapsiblesection.tsx","./src/components/ui/input.tsx","./src/components/ui/label.tsx","./src/components/ui/searchfield.tsx","./src/components/ui/segmentedtabs.tsx","./src/components/ui/select.test.tsx","./src/components/ui/select.tsx","./src/components/ui/sidebaritem.tsx","./src/components/ui/slider.tsx","./src/components/ui/switch.tsx","./src/components/ui/textarea.tsx","./src/components/ui/toastcontext.tsx","./src/components/ui/editorfieldstyles.ts","./src/config/aiproviders.test.ts","./src/config/aiproviders.ts","./src/config/rolloutflags.ts","./src/context/architecturelintcontext.tsx","./src/context/cinematicexportcontext.tsx","./src/context/diagramdiffcontext.tsx","./src/diagram-types/registerbuiltinplugins.test.ts","./src/diagram-types/registerbuiltinplugins.ts","./src/diagram-types/registerbuiltinpropertypanels.test.ts","./src/diagram-types/registerbuiltinpropertypanels.ts","./src/diagram-types/architecture/fuzzcorpus.test.ts","./src/diagram-types/architecture/plugin.test.ts","./src/diagram-types/architecture/plugin.ts","./src/diagram-types/classdiagram/fuzzcorpus.test.ts","./src/diagram-types/classdiagram/plugin.test.ts","./src/diagram-types/classdiagram/plugin.ts","./src/diagram-types/core/contracts.ts","./src/diagram-types/core/index.ts","./src/diagram-types/core/propertypanels.test.ts","./src/diagram-types/core/propertypanels.ts","./src/diagram-types/core/registry.ts","./src/diagram-types/erdiagram/fuzzcorpus.test.ts","./src/diagram-types/erdiagram/plugin.test.ts","./src/diagram-types/erdiagram/plugin.ts","./src/diagram-types/flowchart/plugin.ts","./src/diagram-types/journey/fuzzcorpus.test.ts","./src/diagram-types/journey/plugin.test.ts","./src/diagram-types/journey/plugin.ts","./src/diagram-types/mindmap/fuzzcorpus.test.ts","./src/diagram-types/mindmap/plugin.test.ts","./src/diagram-types/mindmap/plugin.ts","./src/diagram-types/sequence/plugin.test.ts","./src/diagram-types/sequence/plugin.ts","./src/diagram-types/statediagram/plugin.test.ts","./src/diagram-types/statediagram/plugin.ts","./src/docs/docsroutes.ts","./src/docs/publicdocscatalog.js","./src/hooks/edgeconnectinteractions.test.ts","./src/hooks/edgeconnectinteractions.ts","./src/hooks/flowexportviewport.test.ts","./src/hooks/flowexportviewport.ts","./src/hooks/mindmaptopicactionrequest.ts","./src/hooks/nodelabeleditrequest.test.ts","./src/hooks/nodelabeleditrequest.ts","./src/hooks/nodequickcreaterequest.test.ts","./src/hooks/nodequickcreaterequest.ts","./src/hooks/snapshotpolicy.test.ts","./src/hooks/snapshotpolicy.ts","./src/hooks/useaigeneration.ts","./src/hooks/useanimatededgeperformancewarning.test.ts","./src/hooks/useanimatededgeperformancewarning.ts","./src/hooks/useclipboardoperations.ts","./src/hooks/usedesignsystem.ts","./src/hooks/useedgeinteractions.ts","./src/hooks/useedgeoperations.ts","./src/hooks/usefloweditoractions.test.ts","./src/hooks/usefloweditoractions.ts","./src/hooks/usefloweditorcallbacks.ts","./src/hooks/usefloweditorcollaboration.test.ts","./src/hooks/usefloweditorcollaboration.ts","./src/hooks/usefloweditoruistate.ts","./src/hooks/useflowexport.ts","./src/hooks/useflowhistory.test.ts","./src/hooks/useflowhistory.ts","./src/hooks/useflowoperations.ts","./src/hooks/useinfrasync.ts","./src/hooks/useinlinenodetextedit.test.ts","./src/hooks/useinlinenodetextedit.ts","./src/hooks/usekeyboardshortcuts.test.ts","./src/hooks/usekeyboardshortcuts.ts","./src/hooks/uselayoutoperations.ts","./src/hooks/usemarkdowneditor.ts","./src/hooks/usemodifierkeys.test.ts","./src/hooks/usemodifierkeys.ts","./src/hooks/usenodeoperations.ts","./src/hooks/useplayback.ts","./src/hooks/usesnapshots.ts","./src/hooks/usestoragepressureguard.ts","./src/hooks/usestructuredlisteditor.ts","./src/hooks/usestyleclipboard.test.ts","./src/hooks/usestyleclipboard.ts","./src/hooks/ai-generation/chathistorystorage.test.ts","./src/hooks/ai-generation/chathistorystorage.ts","./src/hooks/ai-generation/codetoarchitecture.ts","./src/hooks/ai-generation/graphcomposer.test.ts","./src/hooks/ai-generation/graphcomposer.ts","./src/hooks/ai-generation/nodeactionprompts.test.ts","./src/hooks/ai-generation/nodeactionprompts.ts","./src/hooks/ai-generation/openapiparser.test.ts","./src/hooks/ai-generation/openapiparser.ts","./src/hooks/ai-generation/openapitosequence.ts","./src/hooks/ai-generation/positionpreservingapply.test.ts","./src/hooks/ai-generation/positionpreservingapply.ts","./src/hooks/ai-generation/readiness.test.ts","./src/hooks/ai-generation/readiness.ts","./src/hooks/ai-generation/requestlifecycle.test.ts","./src/hooks/ai-generation/requestlifecycle.ts","./src/hooks/ai-generation/sqlparser.test.ts","./src/hooks/ai-generation/sqlparser.ts","./src/hooks/ai-generation/sqltoerd.ts","./src/hooks/ai-generation/terraformtocloud.ts","./src/hooks/edge-operations/utils.test.ts","./src/hooks/edge-operations/utils.ts","./src/hooks/flow-editor-actions/exporthandlers.test.ts","./src/hooks/flow-editor-actions/exporthandlers.ts","./src/hooks/flow-editor-actions/helpers.ts","./src/hooks/flow-editor-actions/layouthandlers.test.ts","./src/hooks/flow-editor-actions/layouthandlers.ts","./src/hooks/flow-export/diagramdocumenttransfer.test.ts","./src/hooks/flow-export/diagramdocumenttransfer.ts","./src/hooks/flow-export/exportcapture.ts","./src/hooks/flow-operations/useflowcoreactions.ts","./src/hooks/node-operations/createconnectedsibling.ts","./src/hooks/node-operations/dragstopreconcilepolicy.test.ts","./src/hooks/node-operations/dragstopreconcilepolicy.ts","./src/hooks/node-operations/routingduringdrag.test.ts","./src/hooks/node-operations/routingduringdrag.ts","./src/hooks/node-operations/usearchitecturenodeoperations.test.ts","./src/hooks/node-operations/usearchitecturenodeoperations.ts","./src/hooks/node-operations/usemindmapnodeoperations.test.ts","./src/hooks/node-operations/usemindmapnodeoperations.ts","./src/hooks/node-operations/usenodedragoperations.test.ts","./src/hooks/node-operations/usenodedragoperations.ts","./src/hooks/node-operations/usenodeoperationadders.ts","./src/hooks/node-operations/utils.test.ts","./src/hooks/node-operations/utils.ts","./src/i18n/config.test.ts","./src/i18n/config.ts","./src/i18n/strictmodelocalecoverage.test.ts","./src/i18n/usedlocalecoverage.test.ts","./src/lib/architecturetemplates.test.ts","./src/lib/architecturetemplates.ts","./src/lib/brand.ts","./src/lib/classmembers.ts","./src/lib/connectcreationpolicy.test.ts","./src/lib/connectcreationpolicy.ts","./src/lib/devperformance.ts","./src/lib/entityfields.ts","./src/lib/ertoclassconversion.test.ts","./src/lib/ertoclassconversion.ts","./src/lib/exportfilename.test.ts","./src/lib/exportfilename.ts","./src/lib/flowminddslparserv2.test.ts","./src/lib/flowminddslparserv2.ts","./src/lib/genericshapepolicy.ts","./src/lib/id.ts","./src/lib/index.ts","./src/lib/legacybranding.ts","./src/lib/logger.ts","./src/lib/mermaidparser.ts","./src/lib/mermaidparserhelpers.ts","./src/lib/mindmaplayout.test.ts","./src/lib/mindmaplayout.ts","./src/lib/mindmaptree.ts","./src/lib/nodehandles.ts","./src/lib/nodeparent.ts","./src/lib/openflowdslparser.ts","./src/lib/openflowdslparserv2.ts","./src/lib/reactflowcompat.ts","./src/lib/reconnectedge.test.ts","./src/lib/reconnectedge.ts","./src/lib/relationsemantics.test.ts","./src/lib/relationsemantics.ts","./src/lib/releasestaleelkroutes.test.ts","./src/lib/releasestaleelkroutes.ts","./src/lib/result.ts","./src/lib/storagepressure.test.ts","./src/lib/storagepressure.ts","./src/lib/types.ts","./src/services/aligndistribute.ts","./src/services/aiservice.test.ts","./src/services/aiservice.ts","./src/services/animatedexport.test.ts","./src/services/animatedexport.ts","./src/services/architectureroundtrip.test.ts","./src/services/canonicalserialization.test.ts","./src/services/canonicalserialization.ts","./src/services/composediagramfordisplay.test.ts","./src/services/composediagramfordisplay.ts","./src/services/diagramdocument.test.ts","./src/services/diagramdocument.ts","./src/services/domainlibrary.test.ts","./src/services/domainlibrary.ts","./src/services/elklayout.test.ts","./src/services/elklayout.ts","./src/services/exportservice.test.ts","./src/services/exportservice.ts","./src/services/figmaexportservice.ts","./src/services/flowchartroundtrip.test.ts","./src/services/geminiservice.ts","./src/services/gifencoder.test.ts","./src/services/gifencoder.ts","./src/services/iconassetcatalog.ts","./src/services/importfidelity.test.ts","./src/services/importfidelity.ts","./src/services/mermaidparser.test.ts","./src/services/openflowdslexporter.test.ts","./src/services/openflowdslexporter.ts","./src/services/openflowdslparser.test.ts","./src/services/openflowroundtripgolden.test.ts","./src/services/openflowroundtripgoldenfixtures.ts","./src/services/operationfeedback.ts","./src/services/remainingfamiliesroundtrip.test.ts","./src/services/smartedgerouting.test.ts","./src/services/smartedgerouting.ts","./src/services/statediagramroundtrip.test.ts","./src/services/templates.selector.test.ts","./src/services/templates.ts","./src/services/ai/contextserializer.test.ts","./src/services/ai/contextserializer.ts","./src/services/architecturelint/defaultrules.ts","./src/services/architecturelint/ruleengine.test.ts","./src/services/architecturelint/ruleengine.ts","./src/services/architecturelint/rulelibrary.ts","./src/services/architecturelint/types.ts","./src/services/architecturelint/workspacerules.ts","./src/services/collaboration/canvasdiff.test.ts","./src/services/collaboration/canvasdiff.ts","./src/services/collaboration/comments.test.ts","./src/services/collaboration/comments.ts","./src/services/collaboration/contracts.test.ts","./src/services/collaboration/contracts.ts","./src/services/collaboration/hookutils.ts","./src/services/collaboration/presenceviewmodel.test.ts","./src/services/collaboration/presenceviewmodel.ts","./src/services/collaboration/reducer.test.ts","./src/services/collaboration/reducer.ts","./src/services/collaboration/roomconfig.ts","./src/services/collaboration/roomlink.test.ts","./src/services/collaboration/roomlink.ts","./src/services/collaboration/runtimecontroller.test.ts","./src/services/collaboration/runtimecontroller.ts","./src/services/collaboration/runtimehookutils.test.ts","./src/services/collaboration/runtimehookutils.ts","./src/services/collaboration/session.test.ts","./src/services/collaboration/session.ts","./src/services/collaboration/storebridge.test.ts","./src/services/collaboration/storebridge.ts","./src/services/collaboration/transport.test.ts","./src/services/collaboration/transport.ts","./src/services/collaboration/transportfactory.test.ts","./src/services/collaboration/transportfactory.ts","./src/services/collaboration/types.ts","./src/services/collaboration/versioning.test.ts","./src/services/collaboration/versioning.ts","./src/services/collaboration/yjspeertransport.test.ts","./src/services/collaboration/yjspeertransport.ts","./src/services/diagramdiff/diffengine.ts","./src/services/elk-layout/determinism.ts","./src/services/elk-layout/options.ts","./src/services/elk-layout/types.ts","./src/services/export/cinematicbuildplan.test.ts","./src/services/export/cinematicbuildplan.ts","./src/services/export/cinematicrenderstate.test.ts","./src/services/export/cinematicrenderstate.ts","./src/services/export/formatting.ts","./src/services/export/mermaidbuilder.test.ts","./src/services/export/mermaidbuilder.ts","./src/services/export/pdfdocument.test.ts","./src/services/export/pdfdocument.ts","./src/services/export/plantumlbuilder.ts","./src/services/figma/edgehelpers.ts","./src/services/figma/iconhelpers.ts","./src/services/figma/nodelayers.ts","./src/services/figma/themehelpers.ts","./src/services/figmaimport/figmaapiclient.ts","./src/services/infrasync/dockercomposeparser.test.ts","./src/services/infrasync/dockercomposeparser.ts","./src/services/infrasync/infratodsl.test.ts","./src/services/infrasync/infratodsl.ts","./src/services/infrasync/kubernetesparser.test.ts","./src/services/infrasync/kubernetesparser.ts","./src/services/infrasync/terraformstateparser.test.ts","./src/services/infrasync/terraformstateparser.ts","./src/services/infrasync/types.ts","./src/services/mermaid/detectdiagramtype.test.ts","./src/services/mermaid/detectdiagramtype.ts","./src/services/mermaid/diagnosticformatting.test.ts","./src/services/mermaid/diagnosticformatting.ts","./src/services/mermaid/parsemermaidbytype.test.ts","./src/services/mermaid/parsemermaidbytype.ts","./src/services/mermaid/strictmodediagnosticspresentation.test.ts","./src/services/mermaid/strictmodediagnosticspresentation.ts","./src/services/mermaid/strictmodeguidance.test.ts","./src/services/mermaid/strictmodeguidance.ts","./src/services/mermaid/strictmodeuxregression.test.ts","./src/services/offline/registerappshellserviceworker.test.ts","./src/services/offline/registerappshellserviceworker.ts","./src/services/onboarding/config.ts","./src/services/onboarding/events.test.ts","./src/services/onboarding/events.ts","./src/services/playback/contracts.test.ts","./src/services/playback/contracts.ts","./src/services/playback/model.test.ts","./src/services/playback/model.ts","./src/services/playback/studio.test.ts","./src/services/playback/studio.ts","./src/services/sequence/sequencemessage.test.ts","./src/services/sequence/sequencemessage.ts","./src/services/shapelibrary/bootstrap.test.ts","./src/services/shapelibrary/bootstrap.ts","./src/services/shapelibrary/ingestionpipeline.test.ts","./src/services/shapelibrary/ingestionpipeline.ts","./src/services/shapelibrary/manifestvalidation.test.ts","./src/services/shapelibrary/manifestvalidation.ts","./src/services/shapelibrary/providercatalog.test.ts","./src/services/shapelibrary/providercatalog.ts","./src/services/shapelibrary/registry.test.ts","./src/services/shapelibrary/registry.ts","./src/services/shapelibrary/starterpacks.ts","./src/services/shapelibrary/types.ts","./src/services/storage/flowpersiststorage.test.ts","./src/services/storage/flowpersiststorage.ts","./src/services/storage/indexeddbschema.test.ts","./src/services/storage/indexeddbschema.ts","./src/services/storage/indexeddbstatestorage.test.ts","./src/services/storage/indexeddbstatestorage.ts","./src/services/storage/localfirstrepository.ts","./src/services/storage/localfirstruntime.ts","./src/services/storage/snapshotstorage.test.ts","./src/services/storage/snapshotstorage.ts","./src/services/storage/storagetelemetry.test.ts","./src/services/storage/storagetelemetry.ts","./src/services/storage/storagetelemetrysink.test.ts","./src/services/storage/storagetelemetrysink.ts","./src/services/storage/uilocalstorage.test.ts","./src/services/storage/uilocalstorage.ts","./src/services/templatelibrary/registry.test.ts","./src/services/templatelibrary/registry.ts","./src/services/templatelibrary/startertemplates.assets.test.ts","./src/services/templatelibrary/startertemplates.test.ts","./src/services/templatelibrary/startertemplates.ts","./src/services/templatelibrary/types.ts","./src/store/aisettings.test.ts","./src/store/aisettings.ts","./src/store/aisettingspersistence.ts","./src/store/canvashooks.ts","./src/store/defaults.ts","./src/store/designsystemhooks.ts","./src/store/historyhooks.ts","./src/store/persistence.test.ts","./src/store/persistence.ts","./src/store/selectionhooks.ts","./src/store/tabhooks.ts","./src/store/types.ts","./src/store/viewhooks.ts","./src/store/actions/createaiandselectionactions.ts","./src/store/actions/createcanvasactions.ts","./src/store/actions/createdesignsystemactions.ts","./src/store/actions/createhistoryactions.ts","./src/store/actions/createlayeractions.ts","./src/store/actions/createtabactions.ts","./src/store/actions/createviewactions.ts"],"version":"5.8.3"}
\ No newline at end of file
+{"root":["./src/app.tsx","./src/constants.test.ts","./src/constants.ts","./src/index.tsx","./src/store.test.ts","./src/store.ts","./src/theme.ts","./src/app/routestate.test.ts","./src/app/routestate.ts","./src/components/annotationnode.tsx","./src/components/commandbar.test.tsx","./src/components/commandbar.tsx","./src/components/connectmenu.test.tsx","./src/components/connectmenu.tsx","./src/components/contextmenu.tsx","./src/components/customconnectionline.tsx","./src/components/customedge.tsx","./src/components/customnode.handleinteraction.test.tsx","./src/components/customnode.tsx","./src/components/designsystem.integration.test.tsx","./src/components/diagramviewer.tsx","./src/components/errorboundary.tsx","./src/components/exportmenu.tsx","./src/components/exportmenupanel.test.tsx","./src/components/exportmenupanel.tsx","./src/components/flowcanvas.tsx","./src/components/floweditor.tsx","./src/components/floweditoremptystate.tsx","./src/components/floweditorlayoutoverlay.tsx","./src/components/floweditorpanels.test.tsx","./src/components/floweditorpanels.tsx","./src/components/flowtabs.tsx","./src/components/groupnode.tsx","./src/components/homepage.integration.test.tsx","./src/components/homepage.tsx","./src/components/iconmap.test.tsx","./src/components/iconmap.ts","./src/components/imagenode.tsx","./src/components/inlinetexteditsurface.test.tsx","./src/components/inlinetexteditsurface.tsx","./src/components/keyboardshortcutsmodal.tsx","./src/components/languageselector.tsx","./src/components/markdownrenderer.tsx","./src/components/memoizedmarkdown.tsx","./src/components/navigationcontrols.tsx","./src/components/nodechrome.tsx","./src/components/nodequickcreatebuttons.tsx","./src/components/nodetransformcontrols.tsx","./src/components/playbackcontrols.tsx","./src/components/propertiespanel.tsx","./src/components/rightrail.tsx","./src/components/sectionnode.tsx","./src/components/shareembedmodal.tsx","./src/components/sharemodal.test.tsx","./src/components/sharemodal.tsx","./src/components/sidebarshell.tsx","./src/components/snapshotspanel.tsx","./src/components/studioaipanel.test.tsx","./src/components/studioaipanel.tsx","./src/components/studiocodepanel.test.tsx","./src/components/studiocodepanel.tsx","./src/components/studiopanel.test.tsx","./src/components/studiopanel.tsx","./src/components/studioplaybackpanel.test.tsx","./src/components/studioplaybackpanel.tsx","./src/components/swimlanenode.tsx","./src/components/textnode.tsx","./src/components/toolbar.tsx","./src/components/tooltip.tsx","./src/components/topnav.tsx","./src/components/welcomemodal.tsx","./src/components/annotationtheme.ts","./src/components/container-nodes.handleinteraction.test.tsx","./src/components/editorsurfacetiers.ts","./src/components/handleinteraction.test.ts","./src/components/handleinteraction.ts","./src/components/handleinteractionusage.test.ts","./src/components/lightweight-nodes.handleinteraction.test.tsx","./src/components/markdownsyntax.ts","./src/components/sharemodalcontent.ts","./src/components/studioaicopy.ts","./src/components/transformdiagnostics.test.ts","./src/components/transformdiagnostics.ts","./src/components/useactivenodeselection.ts","./src/components/useexportmenu.ts","./src/components/settingsmodal/aisettings.tsx","./src/components/settingsmodal/generalsettings.tsx","./src/components/settingsmodal/privacysettings.tsx","./src/components/settingsmodal/settingsmodal.test.tsx","./src/components/settingsmodal/settingsmodal.tsx","./src/components/settingsmodal/shortcutssettings.tsx","./src/components/settingsmodal/ai/advancedendpointsection.tsx","./src/components/settingsmodal/ai/customheaderseditor.tsx","./src/components/settingsmodal/ai/privacysection.tsx","./src/components/settingsmodal/ai/providericon.tsx","./src/components/settingsmodal/ai/providersection.tsx","./src/components/settingsmodal/ai/step.tsx","./src/components/app/docssiteredirect.test.tsx","./src/components/app/docssiteredirect.tsx","./src/components/app/mobileworkspacegate.test.tsx","./src/components/app/mobileworkspacegate.tsx","./src/components/app/routeloadingfallback.test.tsx","./src/components/app/routeloadingfallback.tsx","./src/components/app/mobileworkspacegatecopy.ts","./src/components/app/routeloadingcopy.ts","./src/components/architecture-lint/lintrulespanel.tsx","./src/components/command-bar/assetsview.test.tsx","./src/components/command-bar/assetsview.tsx","./src/components/command-bar/designsystemeditor.tsx","./src/components/command-bar/designsystemview.tsx","./src/components/command-bar/figmaimportpanel.tsx","./src/components/command-bar/importview.tsx","./src/components/command-bar/layersview.tsx","./src/components/command-bar/layoutview.tsx","./src/components/command-bar/pagesview.tsx","./src/components/command-bar/rootview.test.tsx","./src/components/command-bar/rootview.tsx","./src/components/command-bar/searchview.tsx","./src/components/command-bar/templatesview.tsx","./src/components/command-bar/viewheader.tsx","./src/components/command-bar/visualsview.tsx","./src/components/command-bar/applycodechanges.ts","./src/components/command-bar/assetsviewconstants.ts","./src/components/command-bar/searchquery.test.ts","./src/components/command-bar/searchquery.ts","./src/components/command-bar/types.ts","./src/components/command-bar/useaiviewstate.test.tsx","./src/components/command-bar/useaiviewstate.ts","./src/components/command-bar/usecloudassetcatalog.ts","./src/components/command-bar/usecommandbarcommands.test.tsx","./src/components/command-bar/usecommandbarcommands.tsx","./src/components/custom-edge/customedgewrapper.tsx","./src/components/custom-edge/sequencemessageedge.test.tsx","./src/components/custom-edge/sequencemessageedge.tsx","./src/components/custom-edge/animatededgepresentation.test.ts","./src/components/custom-edge/animatededgepresentation.ts","./src/components/custom-edge/classrelationsemantics.test.ts","./src/components/custom-edge/classrelationsemantics.ts","./src/components/custom-edge/edgerendermode.ts","./src/components/custom-edge/pathutils.test.ts","./src/components/custom-edge/pathutils.ts","./src/components/custom-edge/pathutilsgeometry.ts","./src/components/custom-edge/pathutilssiblingrouting.ts","./src/components/custom-edge/pathutilstypes.ts","./src/components/custom-edge/relationroutingsemantics.test.ts","./src/components/custom-edge/relationroutingsemantics.ts","./src/components/custom-edge/standardedgemarkers.test.ts","./src/components/custom-edge/standardedgemarkers.ts","./src/components/custom-nodes/architecturenode.handleinteraction.test.tsx","./src/components/custom-nodes/architecturenode.tsx","./src/components/custom-nodes/browsernode.tsx","./src/components/custom-nodes/classentitynode.handleinteraction.test.tsx","./src/components/custom-nodes/classnode.tsx","./src/components/custom-nodes/entitynode.tsx","./src/components/custom-nodes/journeynode.tsx","./src/components/custom-nodes/mindmapnode.tsx","./src/components/custom-nodes/mobilenode.tsx","./src/components/custom-nodes/sequenceparticipantnode.tsx","./src/components/custom-nodes/structurednodehandles.tsx","./src/components/custom-nodes/visualnodes.handleinteraction.test.tsx","./src/components/custom-nodes/browservariantrenderer.tsx","./src/components/custom-nodes/mobilevariantrenderer.tsx","./src/components/custom-nodes/structuredlistnavigation.test.ts","./src/components/custom-nodes/structuredlistnavigation.ts","./src/components/diagram-diff/diffmodebanner.tsx","./src/components/flow-canvas/flowcanvasalignmentguidesoverlay.tsx","./src/components/flow-canvas/flowcanvasoverlays.tsx","./src/components/flow-canvas/alignmentguides.test.ts","./src/components/flow-canvas/alignmentguides.ts","./src/components/flow-canvas/flowcanvasreactflowcontracts.ts","./src/components/flow-canvas/flowcanvastypes.test.ts","./src/components/flow-canvas/flowcanvastypes.tsx","./src/components/flow-canvas/largegraphsafetymode.test.ts","./src/components/flow-canvas/largegraphsafetymode.ts","./src/components/flow-canvas/nodechromecoverage.test.ts","./src/components/flow-canvas/pastehelpers.test.ts","./src/components/flow-canvas/pastehelpers.ts","./src/components/flow-canvas/useflowcanvasalignmentguides.ts","./src/components/flow-canvas/useflowcanvasconnectionstate.ts","./src/components/flow-canvas/useflowcanvascontextactions.ts","./src/components/flow-canvas/useflowcanvasdragdrop.ts","./src/components/flow-canvas/useflowcanvasinteractionlod.ts","./src/components/flow-canvas/useflowcanvasmenus.ts","./src/components/flow-canvas/useflowcanvasmenusandactions.test.tsx","./src/components/flow-canvas/useflowcanvasmenusandactions.ts","./src/components/flow-canvas/useflowcanvasnodedraghandlers.ts","./src/components/flow-canvas/useflowcanvaspaste.ts","./src/components/flow-canvas/useflowcanvasreactflowconfig.test.ts","./src/components/flow-canvas/useflowcanvasreactflowconfig.ts","./src/components/flow-canvas/useflowcanvasselectiontools.test.tsx","./src/components/flow-canvas/useflowcanvasselectiontools.ts","./src/components/flow-canvas/useflowcanvasviewstate.test.ts","./src/components/flow-canvas/useflowcanvasviewstate.ts","./src/components/flow-canvas/useflowcanvaszoomlod.ts","./src/components/flow-editor/collaborationpresenceoverlay.test.tsx","./src/components/flow-editor/collaborationpresenceoverlay.tsx","./src/components/flow-editor/floweditorchrome.tsx","./src/components/flow-editor/buildfloweditorcontrollerparams.ts","./src/components/flow-editor/buildfloweditorscreencontrollerparams.ts","./src/components/flow-editor/floweditorchromeprops.ts","./src/components/flow-editor/infradslapply.test.ts","./src/components/flow-editor/infradslapply.ts","./src/components/flow-editor/panelprops.test.ts","./src/components/flow-editor/panelprops.ts","./src/components/flow-editor/shouldexitstudioonselection.test.ts","./src/components/flow-editor/shouldexitstudioonselection.ts","./src/components/flow-editor/usecollaborationnodepositions.ts","./src/components/flow-editor/usefloweditorcontroller.ts","./src/components/flow-editor/usefloweditorinteractionbindings.ts","./src/components/flow-editor/usefloweditorpanelactions.ts","./src/components/flow-editor/usefloweditorpanelprops.ts","./src/components/flow-editor/usefloweditorruntime.ts","./src/components/flow-editor/usefloweditorscreenbehavior.ts","./src/components/flow-editor/usefloweditorscreenmodel.ts","./src/components/flow-editor/usefloweditorscreenstate.ts","./src/components/flow-editor/usefloweditorshellcontroller.test.tsx","./src/components/flow-editor/usefloweditorshellcontroller.ts","./src/components/flow-editor/usefloweditorstudiocontroller.test.tsx","./src/components/flow-editor/usefloweditorstudiocontroller.ts","./src/components/flow-editor/useinfradslapply.ts","./src/components/home/homedashboard.tsx","./src/components/home/homeflowdialogs.tsx","./src/components/home/homesettingsview.tsx","./src/components/home/homesidebar.tsx","./src/components/home/welcomemodalstate.ts","./src/components/icons/assetsicon.tsx","./src/components/icons/openflowlogo.tsx","./src/components/infra-sync/infrasyncpanel.test.tsx","./src/components/infra-sync/infrasyncpanel.tsx","./src/components/journey/journeyscorecontrol.test.tsx","./src/components/journey/journeyscorecontrol.tsx","./src/components/properties/bulknodeproperties.tsx","./src/components/properties/colorpicker.test.tsx","./src/components/properties/colorpicker.tsx","./src/components/properties/customcolorpopover.tsx","./src/components/properties/diagramnodepropertiesrouter.test.ts","./src/components/properties/diagramnodepropertiesrouter.tsx","./src/components/properties/edgeproperties.tsx","./src/components/properties/iconpicker.tsx","./src/components/properties/icontilepickerprimitives.tsx","./src/components/properties/imageupload.tsx","./src/components/properties/inspectorprimitives.tsx","./src/components/properties/nodeactionbuttons.tsx","./src/components/properties/nodecontentsection.tsx","./src/components/properties/nodeimagesettingssection.tsx","./src/components/properties/nodeproperties.tsx","./src/components/properties/nodetextstylesection.tsx","./src/components/properties/nodewireframevariantsection.tsx","./src/components/properties/propertysliderrow.tsx","./src/components/properties/segmentedchoice.tsx","./src/components/properties/shapeselector.tsx","./src/components/properties/swatchpicker.tsx","./src/components/properties/colorpickerutils.ts","./src/components/properties/propertyinputbehavior.test.ts","./src/components/properties/propertyinputbehavior.ts","./src/components/properties/wireframevariants.ts","./src/components/properties/edge/architectureedgesemanticssection.tsx","./src/components/properties/edge/edgecolorsection.tsx","./src/components/properties/edge/edgeconditionsection.tsx","./src/components/properties/edge/edgelabelsection.tsx","./src/components/properties/edge/edgerelationsection.test.tsx","./src/components/properties/edge/edgerelationsection.tsx","./src/components/properties/edge/edgeroutesection.test.tsx","./src/components/properties/edge/edgeroutesection.tsx","./src/components/properties/edge/edgestylesection.tsx","./src/components/properties/edge/sequencemessagesection.tsx","./src/components/properties/edge/architecturesemantics.test.ts","./src/components/properties/edge/architecturesemantics.ts","./src/components/properties/edge/edgelabelmodel.test.ts","./src/components/properties/edge/edgelabelmodel.ts","./src/components/properties/edge/errelationoptions.ts","./src/components/properties/families/architecturenodeproperties.test.tsx","./src/components/properties/families/architecturenodeproperties.tsx","./src/components/properties/families/architecturenodesection.tsx","./src/components/properties/families/classdiagramnodeproperties.tsx","./src/components/properties/families/classmemberlisteditor.tsx","./src/components/properties/families/classnodesection.tsx","./src/components/properties/families/erdiagramnodeproperties.tsx","./src/components/properties/families/entityfieldlisteditor.tsx","./src/components/properties/families/entitynodesection.tsx","./src/components/properties/families/journeynodeproperties.tsx","./src/components/properties/families/journeynodesection.tsx","./src/components/properties/families/mindmapnodeproperties.test.tsx","./src/components/properties/families/mindmapnodeproperties.tsx","./src/components/properties/families/sequencenodeproperties.tsx","./src/components/properties/families/sequencenodesection.tsx","./src/components/properties/families/structuredtextlisteditor.tsx","./src/components/studio-code-panel/usestudiocodepanelcontroller.test.tsx","./src/components/studio-code-panel/usestudiocodepanelcontroller.ts","./src/components/toolbar/toolbaraddmenu.tsx","./src/components/toolbar/toolbaraddmenupanel.tsx","./src/components/toolbar/toolbarhistorycontrols.tsx","./src/components/toolbar/toolbarmodecontrols.tsx","./src/components/toolbar/toolbarbuttonstyles.ts","./src/components/top-nav/topnavactions.tsx","./src/components/top-nav/topnavbrand.tsx","./src/components/top-nav/topnavmenu.test.tsx","./src/components/top-nav/topnavmenu.tsx","./src/components/top-nav/topnavmenupanel.tsx","./src/components/top-nav/usetopnavstate.ts","./src/components/ui/button.tsx","./src/components/ui/collapsiblesection.tsx","./src/components/ui/input.tsx","./src/components/ui/label.tsx","./src/components/ui/searchfield.tsx","./src/components/ui/segmentedtabs.tsx","./src/components/ui/select.test.tsx","./src/components/ui/select.tsx","./src/components/ui/sidebaritem.tsx","./src/components/ui/slider.tsx","./src/components/ui/switch.tsx","./src/components/ui/textarea.tsx","./src/components/ui/toastcontext.tsx","./src/components/ui/editorfieldstyles.ts","./src/config/aiproviders.test.ts","./src/config/aiproviders.ts","./src/config/rolloutflags.ts","./src/context/architecturelintcontext.tsx","./src/context/cinematicexportcontext.tsx","./src/context/diagramdiffcontext.tsx","./src/diagram-types/registerbuiltinplugins.test.ts","./src/diagram-types/registerbuiltinplugins.ts","./src/diagram-types/registerbuiltinpropertypanels.test.ts","./src/diagram-types/registerbuiltinpropertypanels.ts","./src/diagram-types/architecture/fuzzcorpus.test.ts","./src/diagram-types/architecture/plugin.test.ts","./src/diagram-types/architecture/plugin.ts","./src/diagram-types/classdiagram/fuzzcorpus.test.ts","./src/diagram-types/classdiagram/plugin.test.ts","./src/diagram-types/classdiagram/plugin.ts","./src/diagram-types/core/contracts.ts","./src/diagram-types/core/index.ts","./src/diagram-types/core/propertypanels.test.ts","./src/diagram-types/core/propertypanels.ts","./src/diagram-types/core/registry.ts","./src/diagram-types/erdiagram/fuzzcorpus.test.ts","./src/diagram-types/erdiagram/plugin.test.ts","./src/diagram-types/erdiagram/plugin.ts","./src/diagram-types/flowchart/plugin.ts","./src/diagram-types/journey/fuzzcorpus.test.ts","./src/diagram-types/journey/plugin.test.ts","./src/diagram-types/journey/plugin.ts","./src/diagram-types/mindmap/fuzzcorpus.test.ts","./src/diagram-types/mindmap/plugin.test.ts","./src/diagram-types/mindmap/plugin.ts","./src/diagram-types/sequence/plugin.test.ts","./src/diagram-types/sequence/plugin.ts","./src/diagram-types/statediagram/plugin.test.ts","./src/diagram-types/statediagram/plugin.ts","./src/docs/docsroutes.ts","./src/docs/publicdocscatalog.js","./src/hooks/edgeconnectinteractions.test.ts","./src/hooks/edgeconnectinteractions.ts","./src/hooks/flowexportviewport.test.ts","./src/hooks/flowexportviewport.ts","./src/hooks/mindmaptopicactionrequest.ts","./src/hooks/nodelabeleditrequest.test.ts","./src/hooks/nodelabeleditrequest.ts","./src/hooks/nodequickcreaterequest.test.ts","./src/hooks/nodequickcreaterequest.ts","./src/hooks/snapshotpolicy.test.ts","./src/hooks/snapshotpolicy.ts","./src/hooks/useaigeneration.ts","./src/hooks/useanimatededgeperformancewarning.test.ts","./src/hooks/useanimatededgeperformancewarning.ts","./src/hooks/useclipboardoperations.ts","./src/hooks/usedesignsystem.ts","./src/hooks/useedgeinteractions.ts","./src/hooks/useedgeoperations.ts","./src/hooks/usefloweditoractions.test.ts","./src/hooks/usefloweditoractions.ts","./src/hooks/usefloweditorcallbacks.ts","./src/hooks/usefloweditorcollaboration.test.ts","./src/hooks/usefloweditorcollaboration.ts","./src/hooks/usefloweditoruistate.ts","./src/hooks/useflowexport.ts","./src/hooks/useflowhistory.test.ts","./src/hooks/useflowhistory.ts","./src/hooks/useflowoperations.ts","./src/hooks/useinfrasync.ts","./src/hooks/useinlinenodetextedit.test.ts","./src/hooks/useinlinenodetextedit.ts","./src/hooks/usekeyboardshortcuts.test.ts","./src/hooks/usekeyboardshortcuts.ts","./src/hooks/uselayoutoperations.ts","./src/hooks/usemarkdowneditor.ts","./src/hooks/usemodifierkeys.test.ts","./src/hooks/usemodifierkeys.ts","./src/hooks/usenodeoperations.ts","./src/hooks/useplayback.ts","./src/hooks/usesnapshots.ts","./src/hooks/usestoragepressureguard.ts","./src/hooks/usestructuredlisteditor.ts","./src/hooks/usestyleclipboard.test.ts","./src/hooks/usestyleclipboard.ts","./src/hooks/ai-generation/chathistorystorage.test.ts","./src/hooks/ai-generation/chathistorystorage.ts","./src/hooks/ai-generation/codetoarchitecture.ts","./src/hooks/ai-generation/graphcomposer.test.ts","./src/hooks/ai-generation/graphcomposer.ts","./src/hooks/ai-generation/nodeactionprompts.test.ts","./src/hooks/ai-generation/nodeactionprompts.ts","./src/hooks/ai-generation/openapiparser.test.ts","./src/hooks/ai-generation/openapiparser.ts","./src/hooks/ai-generation/openapitosequence.ts","./src/hooks/ai-generation/positionpreservingapply.test.ts","./src/hooks/ai-generation/positionpreservingapply.ts","./src/hooks/ai-generation/readiness.test.ts","./src/hooks/ai-generation/readiness.ts","./src/hooks/ai-generation/requestlifecycle.test.ts","./src/hooks/ai-generation/requestlifecycle.ts","./src/hooks/ai-generation/sqlparser.test.ts","./src/hooks/ai-generation/sqlparser.ts","./src/hooks/ai-generation/sqltoerd.ts","./src/hooks/ai-generation/terraformtocloud.ts","./src/hooks/edge-operations/utils.test.ts","./src/hooks/edge-operations/utils.ts","./src/hooks/flow-editor-actions/exporthandlers.test.ts","./src/hooks/flow-editor-actions/exporthandlers.ts","./src/hooks/flow-editor-actions/helpers.ts","./src/hooks/flow-editor-actions/layouthandlers.test.ts","./src/hooks/flow-editor-actions/layouthandlers.ts","./src/hooks/flow-export/diagramdocumenttransfer.test.ts","./src/hooks/flow-export/diagramdocumenttransfer.ts","./src/hooks/flow-export/exportcapture.test.ts","./src/hooks/flow-export/exportcapture.ts","./src/hooks/flow-operations/useflowcoreactions.ts","./src/hooks/node-operations/createconnectedsibling.ts","./src/hooks/node-operations/dragstopreconcilepolicy.test.ts","./src/hooks/node-operations/dragstopreconcilepolicy.ts","./src/hooks/node-operations/routingduringdrag.test.ts","./src/hooks/node-operations/routingduringdrag.ts","./src/hooks/node-operations/usearchitecturenodeoperations.test.ts","./src/hooks/node-operations/usearchitecturenodeoperations.ts","./src/hooks/node-operations/usemindmapnodeoperations.test.ts","./src/hooks/node-operations/usemindmapnodeoperations.ts","./src/hooks/node-operations/usenodedragoperations.test.ts","./src/hooks/node-operations/usenodedragoperations.ts","./src/hooks/node-operations/usenodeoperationadders.ts","./src/hooks/node-operations/utils.test.ts","./src/hooks/node-operations/utils.ts","./src/i18n/config.test.ts","./src/i18n/config.ts","./src/i18n/strictmodelocalecoverage.test.ts","./src/i18n/usedlocalecoverage.test.ts","./src/lib/architecturetemplates.test.ts","./src/lib/architecturetemplates.ts","./src/lib/brand.ts","./src/lib/classmembers.ts","./src/lib/connectcreationpolicy.test.ts","./src/lib/connectcreationpolicy.ts","./src/lib/devperformance.ts","./src/lib/entityfields.ts","./src/lib/ertoclassconversion.test.ts","./src/lib/ertoclassconversion.ts","./src/lib/exportfilename.test.ts","./src/lib/exportfilename.ts","./src/lib/flowminddslparserv2.test.ts","./src/lib/flowminddslparserv2.ts","./src/lib/genericshapepolicy.ts","./src/lib/id.ts","./src/lib/index.ts","./src/lib/legacybranding.ts","./src/lib/logger.ts","./src/lib/mermaidparser.ts","./src/lib/mermaidparserhelpers.ts","./src/lib/mindmaplayout.test.ts","./src/lib/mindmaplayout.ts","./src/lib/mindmaptree.ts","./src/lib/nodehandles.ts","./src/lib/nodeparent.ts","./src/lib/openflowdslparser.ts","./src/lib/openflowdslparserv2.ts","./src/lib/reactflowcompat.ts","./src/lib/reconnectedge.test.ts","./src/lib/reconnectedge.ts","./src/lib/relationsemantics.test.ts","./src/lib/relationsemantics.ts","./src/lib/releasestaleelkroutes.test.ts","./src/lib/releasestaleelkroutes.ts","./src/lib/result.ts","./src/lib/storagepressure.test.ts","./src/lib/storagepressure.ts","./src/lib/types.ts","./src/services/aligndistribute.ts","./src/services/aiservice.test.ts","./src/services/aiservice.ts","./src/services/animatedexport.test.ts","./src/services/animatedexport.ts","./src/services/architectureroundtrip.test.ts","./src/services/canonicalserialization.test.ts","./src/services/canonicalserialization.ts","./src/services/composediagramfordisplay.test.ts","./src/services/composediagramfordisplay.ts","./src/services/diagramdocument.test.ts","./src/services/diagramdocument.ts","./src/services/domainlibrary.test.ts","./src/services/domainlibrary.ts","./src/services/elklayout.test.ts","./src/services/elklayout.ts","./src/services/exportservice.test.ts","./src/services/exportservice.ts","./src/services/figmaexportservice.ts","./src/services/flowchartroundtrip.test.ts","./src/services/geminiservice.ts","./src/services/gifencoder.test.ts","./src/services/gifencoder.ts","./src/services/iconassetcatalog.ts","./src/services/importfidelity.test.ts","./src/services/importfidelity.ts","./src/services/mermaidparser.test.ts","./src/services/openflowdslexporter.test.ts","./src/services/openflowdslexporter.ts","./src/services/openflowdslparser.test.ts","./src/services/openflowroundtripgolden.test.ts","./src/services/openflowroundtripgoldenfixtures.ts","./src/services/operationfeedback.ts","./src/services/remainingfamiliesroundtrip.test.ts","./src/services/smartedgerouting.test.ts","./src/services/smartedgerouting.ts","./src/services/statediagramroundtrip.test.ts","./src/services/templates.selector.test.ts","./src/services/templates.ts","./src/services/ai/contextserializer.test.ts","./src/services/ai/contextserializer.ts","./src/services/architecturelint/defaultrules.ts","./src/services/architecturelint/ruleengine.test.ts","./src/services/architecturelint/ruleengine.ts","./src/services/architecturelint/rulelibrary.ts","./src/services/architecturelint/types.ts","./src/services/architecturelint/workspacerules.ts","./src/services/collaboration/canvasdiff.test.ts","./src/services/collaboration/canvasdiff.ts","./src/services/collaboration/comments.test.ts","./src/services/collaboration/comments.ts","./src/services/collaboration/contracts.test.ts","./src/services/collaboration/contracts.ts","./src/services/collaboration/hookutils.ts","./src/services/collaboration/presenceviewmodel.test.ts","./src/services/collaboration/presenceviewmodel.ts","./src/services/collaboration/reducer.test.ts","./src/services/collaboration/reducer.ts","./src/services/collaboration/roomconfig.ts","./src/services/collaboration/roomlink.test.ts","./src/services/collaboration/roomlink.ts","./src/services/collaboration/runtimecontroller.test.ts","./src/services/collaboration/runtimecontroller.ts","./src/services/collaboration/runtimehookutils.test.ts","./src/services/collaboration/runtimehookutils.ts","./src/services/collaboration/session.test.ts","./src/services/collaboration/session.ts","./src/services/collaboration/storebridge.test.ts","./src/services/collaboration/storebridge.ts","./src/services/collaboration/transport.test.ts","./src/services/collaboration/transport.ts","./src/services/collaboration/transportfactory.test.ts","./src/services/collaboration/transportfactory.ts","./src/services/collaboration/types.ts","./src/services/collaboration/versioning.test.ts","./src/services/collaboration/versioning.ts","./src/services/collaboration/yjspeertransport.test.ts","./src/services/collaboration/yjspeertransport.ts","./src/services/diagramdiff/diffengine.ts","./src/services/elk-layout/determinism.ts","./src/services/elk-layout/options.ts","./src/services/elk-layout/types.ts","./src/services/export/cinematicbuildplan.test.ts","./src/services/export/cinematicbuildplan.ts","./src/services/export/cinematicexporttheme.test.ts","./src/services/export/cinematicexporttheme.ts","./src/services/export/cinematicrenderstate.test.ts","./src/services/export/cinematicrenderstate.ts","./src/services/export/formatting.ts","./src/services/export/mermaidbuilder.test.ts","./src/services/export/mermaidbuilder.ts","./src/services/export/pdfdocument.test.ts","./src/services/export/pdfdocument.ts","./src/services/export/plantumlbuilder.ts","./src/services/figma/edgehelpers.ts","./src/services/figma/iconhelpers.ts","./src/services/figma/nodelayers.ts","./src/services/figma/themehelpers.ts","./src/services/figmaimport/figmaapiclient.ts","./src/services/infrasync/dockercomposeparser.test.ts","./src/services/infrasync/dockercomposeparser.ts","./src/services/infrasync/infratodsl.test.ts","./src/services/infrasync/infratodsl.ts","./src/services/infrasync/kubernetesparser.test.ts","./src/services/infrasync/kubernetesparser.ts","./src/services/infrasync/terraformstateparser.test.ts","./src/services/infrasync/terraformstateparser.ts","./src/services/infrasync/types.ts","./src/services/mermaid/detectdiagramtype.test.ts","./src/services/mermaid/detectdiagramtype.ts","./src/services/mermaid/diagnosticformatting.test.ts","./src/services/mermaid/diagnosticformatting.ts","./src/services/mermaid/parsemermaidbytype.test.ts","./src/services/mermaid/parsemermaidbytype.ts","./src/services/mermaid/strictmodediagnosticspresentation.test.ts","./src/services/mermaid/strictmodediagnosticspresentation.ts","./src/services/mermaid/strictmodeguidance.test.ts","./src/services/mermaid/strictmodeguidance.ts","./src/services/mermaid/strictmodeuxregression.test.ts","./src/services/offline/registerappshellserviceworker.test.ts","./src/services/offline/registerappshellserviceworker.ts","./src/services/onboarding/config.ts","./src/services/onboarding/events.test.ts","./src/services/onboarding/events.ts","./src/services/playback/contracts.test.ts","./src/services/playback/contracts.ts","./src/services/playback/model.test.ts","./src/services/playback/model.ts","./src/services/playback/studio.test.ts","./src/services/playback/studio.ts","./src/services/sequence/sequencemessage.test.ts","./src/services/sequence/sequencemessage.ts","./src/services/shapelibrary/bootstrap.test.ts","./src/services/shapelibrary/bootstrap.ts","./src/services/shapelibrary/ingestionpipeline.test.ts","./src/services/shapelibrary/ingestionpipeline.ts","./src/services/shapelibrary/manifestvalidation.test.ts","./src/services/shapelibrary/manifestvalidation.ts","./src/services/shapelibrary/providercatalog.test.ts","./src/services/shapelibrary/providercatalog.ts","./src/services/shapelibrary/registry.test.ts","./src/services/shapelibrary/registry.ts","./src/services/shapelibrary/starterpacks.ts","./src/services/shapelibrary/types.ts","./src/services/storage/flowpersiststorage.test.ts","./src/services/storage/flowpersiststorage.ts","./src/services/storage/indexeddbschema.test.ts","./src/services/storage/indexeddbschema.ts","./src/services/storage/indexeddbstatestorage.test.ts","./src/services/storage/indexeddbstatestorage.ts","./src/services/storage/localfirstrepository.ts","./src/services/storage/localfirstruntime.ts","./src/services/storage/snapshotstorage.test.ts","./src/services/storage/snapshotstorage.ts","./src/services/storage/storagetelemetry.test.ts","./src/services/storage/storagetelemetry.ts","./src/services/storage/storagetelemetrysink.test.ts","./src/services/storage/storagetelemetrysink.ts","./src/services/storage/uilocalstorage.test.ts","./src/services/storage/uilocalstorage.ts","./src/services/templatelibrary/registry.test.ts","./src/services/templatelibrary/registry.ts","./src/services/templatelibrary/startertemplates.assets.test.ts","./src/services/templatelibrary/startertemplates.test.ts","./src/services/templatelibrary/startertemplates.ts","./src/services/templatelibrary/types.ts","./src/store/aisettings.test.ts","./src/store/aisettings.ts","./src/store/aisettingspersistence.ts","./src/store/canvashooks.ts","./src/store/defaults.ts","./src/store/designsystemhooks.ts","./src/store/historyhooks.ts","./src/store/persistence.test.ts","./src/store/persistence.ts","./src/store/selectionhooks.ts","./src/store/tabhooks.ts","./src/store/types.ts","./src/store/viewhooks.ts","./src/store/actions/createaiandselectionactions.ts","./src/store/actions/createcanvasactions.ts","./src/store/actions/createdesignsystemactions.ts","./src/store/actions/createhistoryactions.ts","./src/store/actions/createlayeractions.ts","./src/store/actions/createtabactions.ts","./src/store/actions/createviewactions.ts"],"version":"5.8.3"}
\ No newline at end of file
diff --git a/web/.astro/types.d.ts b/web/.astro/types.d.ts
index f964fe0c..03d7cc43 100644
--- a/web/.astro/types.d.ts
+++ b/web/.astro/types.d.ts
@@ -1 +1,2 @@
///
+///
\ No newline at end of file
diff --git a/web/public/readme/1.png b/web/public/readme/1.png
new file mode 100644
index 00000000..d59dcd72
Binary files /dev/null and b/web/public/readme/1.png differ
diff --git a/web/src/components/Layout.astro b/web/src/components/Layout.astro
index 1c36d8b3..8f9cbf34 100644
--- a/web/src/components/Layout.astro
+++ b/web/src/components/Layout.astro
@@ -11,7 +11,7 @@ interface Props {
const { title, description, canonicalPath = '/', schema } = Astro.props;
const siteUrl = 'https://openflowkit.com';
const canonicalUrl = new URL(canonicalPath, siteUrl).toString();
-const ogImage = `${siteUrl}/og-image.png`;
+const ogImage = `${siteUrl}/readme/1.png`;
const baseSchemas = [
{
'@context': 'https://schema.org',
@@ -61,10 +61,12 @@ const schemas = [...baseSchemas, ...extraSchemas];
+
+
diff --git a/web/src/components/icons/OpenFlowLogo.tsx b/web/src/components/icons/OpenFlowLogo.tsx
index f2ca0c92..68753d02 100644
--- a/web/src/components/icons/OpenFlowLogo.tsx
+++ b/web/src/components/icons/OpenFlowLogo.tsx
@@ -1,19 +1,14 @@
import React from 'react';
-export const OpenFlowLogo: React.FC<{ className?: string }> = ({ className }) => {
+const LOGO_SRC = '/favicon.svg';
+
+export const OpenFlowLogo: React.FC<{ className?: string }> = ({ className = '' }) => {
return (
-
-
-
+
);
};
diff --git a/web/src/components/landing/AnswerEngineSection.tsx b/web/src/components/landing/AnswerEngineSection.tsx
deleted file mode 100644
index b85a6a67..00000000
--- a/web/src/components/landing/AnswerEngineSection.tsx
+++ /dev/null
@@ -1,96 +0,0 @@
-import React from 'react';
-
-const proofPoints = [
- {
- title: 'Local-first by default',
- description:
- 'Your diagrams, workspace state, and AI-related browser data stay on-device unless you choose to remove them.',
- },
- {
- title: 'Useful for real architecture work',
- description:
- 'OpenFlowKit supports freeform diagramming, architecture mapping, AI-assisted drafting, structured imports, and handoff exports.',
- },
- {
- title: 'Built for editable output',
- description:
- 'You can keep iterating in the canvas, export to Mermaid, or hand work off through SVG, PNG, and Figma-friendly paths.',
- },
-];
-
-const faqs = [
- {
- question: 'What is OpenFlowKit?',
- answer:
- 'OpenFlowKit is an open-source, local-first diagramming tool for architecture diagrams, flowcharts, and AI-assisted visual workflows.',
- },
- {
- question: 'Who is OpenFlowKit for?',
- answer:
- 'It is designed for engineers, architects, technical founders, and product teams who need editable diagrams instead of static AI image output.',
- },
- {
- question: 'Does OpenFlowKit require an account?',
- answer:
- 'No. You can open the app and start diagramming without creating an account.',
- },
- {
- question: 'How does AI work in OpenFlowKit?',
- answer:
- 'AI is optional. You bring your own API key in the settings modal, then use AI to draft, refine, or expand diagrams inside the editor.',
- },
-];
-
-export function AnswerEngineSection(): React.ReactElement {
- return (
-
-
-
-
-
- Why OpenFlowKit
-
-
- A local-first AI diagramming tool built for editable technical work.
-
-
- OpenFlowKit helps teams turn rough system ideas into diagrams they can keep
- editing, exporting, and sharing. It is designed for architecture flows, system
- design, process mapping, and other diagram-heavy workflows where static output is
- not enough.
-
-
-
- {proofPoints.map((item) => (
-
- {item.title}
- {item.description}
-
- ))}
-
-
-
-
-
- Frequently Asked
-
-
- {faqs.map((item) => (
-
- {item.question}
- {item.answer}
-
- ))}
-
-
-
-
-
- );
-}
diff --git a/web/src/components/landing/LandingPage.tsx b/web/src/components/landing/LandingPage.tsx
index 81b914f9..fc8e23a9 100644
--- a/web/src/components/landing/LandingPage.tsx
+++ b/web/src/components/landing/LandingPage.tsx
@@ -1,5 +1,4 @@
import React, { useEffect, useState } from 'react';
-import { AnswerEngineSection } from './AnswerEngineSection';
import { ArchitectureExploded } from './ArchitectureExploded';
import { APP_URL } from './constants';
import { FinalCTASection } from './FinalCTASection';
@@ -46,7 +45,6 @@ export function LandingPage(): React.ReactElement {
-
diff --git a/web/src/components/landing/Navbar.tsx b/web/src/components/landing/Navbar.tsx
index 38a428aa..8bc0813c 100644
--- a/web/src/components/landing/Navbar.tsx
+++ b/web/src/components/landing/Navbar.tsx
@@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react';
-import { ChevronRight, Github, Menu, WandSparkles, X } from 'lucide-react';
+import { ChevronRight, Github, Menu, X } from 'lucide-react';
import { OpenFlowLogo } from '../icons/OpenFlowLogo';
import { Button } from './Button';
import { GITHUB_REPO_URL, NAV_LINKS } from './constants';
@@ -77,9 +77,7 @@ export function Navbar({ isScrolled, onLaunch }: NavbarProps): React.ReactElemen
className="flex items-center gap-2.5 cursor-pointer group select-none min-w-0"
aria-label="Open OpenFlowKit"
>
-
-
-
+
OpenFlowKit
@@ -164,19 +162,17 @@ export function Navbar({ isScrolled, onLaunch }: NavbarProps): React.ReactElemen
- Get Started
-
+ Get Started
-
View on GitHub
diff --git a/web/src/components/landing/constants.ts b/web/src/components/landing/constants.ts
index d6152bad..02ba4d69 100644
--- a/web/src/components/landing/constants.ts
+++ b/web/src/components/landing/constants.ts
@@ -21,7 +21,7 @@ export const PRICING_FEATURES = [
'Export to SVG, PNG, JPG',
'Figma Export',
'Mermaid.js Support',
- 'AI diagram generation (bring your own API key)',
+ 'AI diagram generation (BYOK)',
] as const;
export const LANDING_CONTRIBUTORS = [
diff --git a/web/src/pages/index.astro b/web/src/pages/index.astro
index c8b1a571..5c52e2f6 100644
--- a/web/src/pages/index.astro
+++ b/web/src/pages/index.astro
@@ -43,7 +43,7 @@ const faqSchema = {
---