diff --git a/.agents/skills/impeccable/scripts/live-browser.js b/.agents/skills/impeccable/scripts/live-browser.js index cc1b5bd4f..d4de79ece 100644 --- a/.agents/skills/impeccable/scripts/live-browser.js +++ b/.agents/skills/impeccable/scripts/live-browser.js @@ -2135,6 +2135,15 @@ void main() { function saveSession() { if (!currentSessionId) return; + // Capture the selected element's current viewport-relative top so we + // can restore the same framing after a reload, even if layout shifts. + let scrollAnchor = null; + try { + if (selectedElement && selectedElement.isConnected) { + const r = selectedElement.getBoundingClientRect(); + if (r.width > 0 && r.height > 0) scrollAnchor = { viewportTop: r.top }; + } + } catch {} try { localStorage.setItem(LS_KEY, JSON.stringify({ id: currentSessionId, @@ -2144,6 +2153,7 @@ void main() { expected: expectedVariants, arrived: arrivedVariants, visible: visibleVariant, + scrollAnchor, })); } catch { /* quota exceeded or private mode */ } } @@ -2288,6 +2298,25 @@ void main() { // Set display state BEFORE starting observer (avoid triggering it) if (visibleVariant > 0) showVariantInDOM(currentSessionId, visibleVariant); + // Restore scroll: land the selected element back at the same + // viewport-relative top it had before the reload. Two passes — once + // synchronously, once after fonts/images settle — catch late layout + // shifts without animating the correction. + if (saved?.scrollAnchor && selectedElement) { + try { history.scrollRestoration = 'manual'; } catch {} + const targetTop = saved.scrollAnchor.viewportTop; + const correct = () => { + if (!selectedElement?.isConnected) return; + const delta = selectedElement.getBoundingClientRect().top - targetTop; + if (Math.abs(delta) > 0.5) window.scrollBy({ top: delta, left: 0, behavior: 'instant' }); + }; + correct(); + requestAnimationFrame(() => requestAnimationFrame(correct)); + if (document.fonts?.ready) { + document.fonts.ready.then(() => requestAnimationFrame(correct)).catch(() => {}); + } + } + state = arrivedVariants >= expectedVariants ? 'CYCLING' : 'GENERATING'; showBar(state === 'CYCLING' ? 'cycling' : 'generating'); startScrollTracking(); diff --git a/.claude/skills/impeccable/scripts/live-browser.js b/.claude/skills/impeccable/scripts/live-browser.js index cc1b5bd4f..d4de79ece 100644 --- a/.claude/skills/impeccable/scripts/live-browser.js +++ b/.claude/skills/impeccable/scripts/live-browser.js @@ -2135,6 +2135,15 @@ void main() { function saveSession() { if (!currentSessionId) return; + // Capture the selected element's current viewport-relative top so we + // can restore the same framing after a reload, even if layout shifts. + let scrollAnchor = null; + try { + if (selectedElement && selectedElement.isConnected) { + const r = selectedElement.getBoundingClientRect(); + if (r.width > 0 && r.height > 0) scrollAnchor = { viewportTop: r.top }; + } + } catch {} try { localStorage.setItem(LS_KEY, JSON.stringify({ id: currentSessionId, @@ -2144,6 +2153,7 @@ void main() { expected: expectedVariants, arrived: arrivedVariants, visible: visibleVariant, + scrollAnchor, })); } catch { /* quota exceeded or private mode */ } } @@ -2288,6 +2298,25 @@ void main() { // Set display state BEFORE starting observer (avoid triggering it) if (visibleVariant > 0) showVariantInDOM(currentSessionId, visibleVariant); + // Restore scroll: land the selected element back at the same + // viewport-relative top it had before the reload. Two passes — once + // synchronously, once after fonts/images settle — catch late layout + // shifts without animating the correction. + if (saved?.scrollAnchor && selectedElement) { + try { history.scrollRestoration = 'manual'; } catch {} + const targetTop = saved.scrollAnchor.viewportTop; + const correct = () => { + if (!selectedElement?.isConnected) return; + const delta = selectedElement.getBoundingClientRect().top - targetTop; + if (Math.abs(delta) > 0.5) window.scrollBy({ top: delta, left: 0, behavior: 'instant' }); + }; + correct(); + requestAnimationFrame(() => requestAnimationFrame(correct)); + if (document.fonts?.ready) { + document.fonts.ready.then(() => requestAnimationFrame(correct)).catch(() => {}); + } + } + state = arrivedVariants >= expectedVariants ? 'CYCLING' : 'GENERATING'; showBar(state === 'CYCLING' ? 'cycling' : 'generating'); startScrollTracking(); diff --git a/.cursor/skills/impeccable/scripts/live-browser.js b/.cursor/skills/impeccable/scripts/live-browser.js index cc1b5bd4f..d4de79ece 100644 --- a/.cursor/skills/impeccable/scripts/live-browser.js +++ b/.cursor/skills/impeccable/scripts/live-browser.js @@ -2135,6 +2135,15 @@ void main() { function saveSession() { if (!currentSessionId) return; + // Capture the selected element's current viewport-relative top so we + // can restore the same framing after a reload, even if layout shifts. + let scrollAnchor = null; + try { + if (selectedElement && selectedElement.isConnected) { + const r = selectedElement.getBoundingClientRect(); + if (r.width > 0 && r.height > 0) scrollAnchor = { viewportTop: r.top }; + } + } catch {} try { localStorage.setItem(LS_KEY, JSON.stringify({ id: currentSessionId, @@ -2144,6 +2153,7 @@ void main() { expected: expectedVariants, arrived: arrivedVariants, visible: visibleVariant, + scrollAnchor, })); } catch { /* quota exceeded or private mode */ } } @@ -2288,6 +2298,25 @@ void main() { // Set display state BEFORE starting observer (avoid triggering it) if (visibleVariant > 0) showVariantInDOM(currentSessionId, visibleVariant); + // Restore scroll: land the selected element back at the same + // viewport-relative top it had before the reload. Two passes — once + // synchronously, once after fonts/images settle — catch late layout + // shifts without animating the correction. + if (saved?.scrollAnchor && selectedElement) { + try { history.scrollRestoration = 'manual'; } catch {} + const targetTop = saved.scrollAnchor.viewportTop; + const correct = () => { + if (!selectedElement?.isConnected) return; + const delta = selectedElement.getBoundingClientRect().top - targetTop; + if (Math.abs(delta) > 0.5) window.scrollBy({ top: delta, left: 0, behavior: 'instant' }); + }; + correct(); + requestAnimationFrame(() => requestAnimationFrame(correct)); + if (document.fonts?.ready) { + document.fonts.ready.then(() => requestAnimationFrame(correct)).catch(() => {}); + } + } + state = arrivedVariants >= expectedVariants ? 'CYCLING' : 'GENERATING'; showBar(state === 'CYCLING' ? 'cycling' : 'generating'); startScrollTracking(); diff --git a/.gemini/skills/impeccable/scripts/live-browser.js b/.gemini/skills/impeccable/scripts/live-browser.js index cc1b5bd4f..d4de79ece 100644 --- a/.gemini/skills/impeccable/scripts/live-browser.js +++ b/.gemini/skills/impeccable/scripts/live-browser.js @@ -2135,6 +2135,15 @@ void main() { function saveSession() { if (!currentSessionId) return; + // Capture the selected element's current viewport-relative top so we + // can restore the same framing after a reload, even if layout shifts. + let scrollAnchor = null; + try { + if (selectedElement && selectedElement.isConnected) { + const r = selectedElement.getBoundingClientRect(); + if (r.width > 0 && r.height > 0) scrollAnchor = { viewportTop: r.top }; + } + } catch {} try { localStorage.setItem(LS_KEY, JSON.stringify({ id: currentSessionId, @@ -2144,6 +2153,7 @@ void main() { expected: expectedVariants, arrived: arrivedVariants, visible: visibleVariant, + scrollAnchor, })); } catch { /* quota exceeded or private mode */ } } @@ -2288,6 +2298,25 @@ void main() { // Set display state BEFORE starting observer (avoid triggering it) if (visibleVariant > 0) showVariantInDOM(currentSessionId, visibleVariant); + // Restore scroll: land the selected element back at the same + // viewport-relative top it had before the reload. Two passes — once + // synchronously, once after fonts/images settle — catch late layout + // shifts without animating the correction. + if (saved?.scrollAnchor && selectedElement) { + try { history.scrollRestoration = 'manual'; } catch {} + const targetTop = saved.scrollAnchor.viewportTop; + const correct = () => { + if (!selectedElement?.isConnected) return; + const delta = selectedElement.getBoundingClientRect().top - targetTop; + if (Math.abs(delta) > 0.5) window.scrollBy({ top: delta, left: 0, behavior: 'instant' }); + }; + correct(); + requestAnimationFrame(() => requestAnimationFrame(correct)); + if (document.fonts?.ready) { + document.fonts.ready.then(() => requestAnimationFrame(correct)).catch(() => {}); + } + } + state = arrivedVariants >= expectedVariants ? 'CYCLING' : 'GENERATING'; showBar(state === 'CYCLING' ? 'cycling' : 'generating'); startScrollTracking(); diff --git a/.github/skills/impeccable/scripts/live-browser.js b/.github/skills/impeccable/scripts/live-browser.js index cc1b5bd4f..d4de79ece 100644 --- a/.github/skills/impeccable/scripts/live-browser.js +++ b/.github/skills/impeccable/scripts/live-browser.js @@ -2135,6 +2135,15 @@ void main() { function saveSession() { if (!currentSessionId) return; + // Capture the selected element's current viewport-relative top so we + // can restore the same framing after a reload, even if layout shifts. + let scrollAnchor = null; + try { + if (selectedElement && selectedElement.isConnected) { + const r = selectedElement.getBoundingClientRect(); + if (r.width > 0 && r.height > 0) scrollAnchor = { viewportTop: r.top }; + } + } catch {} try { localStorage.setItem(LS_KEY, JSON.stringify({ id: currentSessionId, @@ -2144,6 +2153,7 @@ void main() { expected: expectedVariants, arrived: arrivedVariants, visible: visibleVariant, + scrollAnchor, })); } catch { /* quota exceeded or private mode */ } } @@ -2288,6 +2298,25 @@ void main() { // Set display state BEFORE starting observer (avoid triggering it) if (visibleVariant > 0) showVariantInDOM(currentSessionId, visibleVariant); + // Restore scroll: land the selected element back at the same + // viewport-relative top it had before the reload. Two passes — once + // synchronously, once after fonts/images settle — catch late layout + // shifts without animating the correction. + if (saved?.scrollAnchor && selectedElement) { + try { history.scrollRestoration = 'manual'; } catch {} + const targetTop = saved.scrollAnchor.viewportTop; + const correct = () => { + if (!selectedElement?.isConnected) return; + const delta = selectedElement.getBoundingClientRect().top - targetTop; + if (Math.abs(delta) > 0.5) window.scrollBy({ top: delta, left: 0, behavior: 'instant' }); + }; + correct(); + requestAnimationFrame(() => requestAnimationFrame(correct)); + if (document.fonts?.ready) { + document.fonts.ready.then(() => requestAnimationFrame(correct)).catch(() => {}); + } + } + state = arrivedVariants >= expectedVariants ? 'CYCLING' : 'GENERATING'; showBar(state === 'CYCLING' ? 'cycling' : 'generating'); startScrollTracking(); diff --git a/.kiro/skills/impeccable/scripts/live-browser.js b/.kiro/skills/impeccable/scripts/live-browser.js index cc1b5bd4f..d4de79ece 100644 --- a/.kiro/skills/impeccable/scripts/live-browser.js +++ b/.kiro/skills/impeccable/scripts/live-browser.js @@ -2135,6 +2135,15 @@ void main() { function saveSession() { if (!currentSessionId) return; + // Capture the selected element's current viewport-relative top so we + // can restore the same framing after a reload, even if layout shifts. + let scrollAnchor = null; + try { + if (selectedElement && selectedElement.isConnected) { + const r = selectedElement.getBoundingClientRect(); + if (r.width > 0 && r.height > 0) scrollAnchor = { viewportTop: r.top }; + } + } catch {} try { localStorage.setItem(LS_KEY, JSON.stringify({ id: currentSessionId, @@ -2144,6 +2153,7 @@ void main() { expected: expectedVariants, arrived: arrivedVariants, visible: visibleVariant, + scrollAnchor, })); } catch { /* quota exceeded or private mode */ } } @@ -2288,6 +2298,25 @@ void main() { // Set display state BEFORE starting observer (avoid triggering it) if (visibleVariant > 0) showVariantInDOM(currentSessionId, visibleVariant); + // Restore scroll: land the selected element back at the same + // viewport-relative top it had before the reload. Two passes — once + // synchronously, once after fonts/images settle — catch late layout + // shifts without animating the correction. + if (saved?.scrollAnchor && selectedElement) { + try { history.scrollRestoration = 'manual'; } catch {} + const targetTop = saved.scrollAnchor.viewportTop; + const correct = () => { + if (!selectedElement?.isConnected) return; + const delta = selectedElement.getBoundingClientRect().top - targetTop; + if (Math.abs(delta) > 0.5) window.scrollBy({ top: delta, left: 0, behavior: 'instant' }); + }; + correct(); + requestAnimationFrame(() => requestAnimationFrame(correct)); + if (document.fonts?.ready) { + document.fonts.ready.then(() => requestAnimationFrame(correct)).catch(() => {}); + } + } + state = arrivedVariants >= expectedVariants ? 'CYCLING' : 'GENERATING'; showBar(state === 'CYCLING' ? 'cycling' : 'generating'); startScrollTracking(); diff --git a/.opencode/skills/impeccable/scripts/live-browser.js b/.opencode/skills/impeccable/scripts/live-browser.js index cc1b5bd4f..d4de79ece 100644 --- a/.opencode/skills/impeccable/scripts/live-browser.js +++ b/.opencode/skills/impeccable/scripts/live-browser.js @@ -2135,6 +2135,15 @@ void main() { function saveSession() { if (!currentSessionId) return; + // Capture the selected element's current viewport-relative top so we + // can restore the same framing after a reload, even if layout shifts. + let scrollAnchor = null; + try { + if (selectedElement && selectedElement.isConnected) { + const r = selectedElement.getBoundingClientRect(); + if (r.width > 0 && r.height > 0) scrollAnchor = { viewportTop: r.top }; + } + } catch {} try { localStorage.setItem(LS_KEY, JSON.stringify({ id: currentSessionId, @@ -2144,6 +2153,7 @@ void main() { expected: expectedVariants, arrived: arrivedVariants, visible: visibleVariant, + scrollAnchor, })); } catch { /* quota exceeded or private mode */ } } @@ -2288,6 +2298,25 @@ void main() { // Set display state BEFORE starting observer (avoid triggering it) if (visibleVariant > 0) showVariantInDOM(currentSessionId, visibleVariant); + // Restore scroll: land the selected element back at the same + // viewport-relative top it had before the reload. Two passes — once + // synchronously, once after fonts/images settle — catch late layout + // shifts without animating the correction. + if (saved?.scrollAnchor && selectedElement) { + try { history.scrollRestoration = 'manual'; } catch {} + const targetTop = saved.scrollAnchor.viewportTop; + const correct = () => { + if (!selectedElement?.isConnected) return; + const delta = selectedElement.getBoundingClientRect().top - targetTop; + if (Math.abs(delta) > 0.5) window.scrollBy({ top: delta, left: 0, behavior: 'instant' }); + }; + correct(); + requestAnimationFrame(() => requestAnimationFrame(correct)); + if (document.fonts?.ready) { + document.fonts.ready.then(() => requestAnimationFrame(correct)).catch(() => {}); + } + } + state = arrivedVariants >= expectedVariants ? 'CYCLING' : 'GENERATING'; showBar(state === 'CYCLING' ? 'cycling' : 'generating'); startScrollTracking(); diff --git a/.pi/skills/impeccable/scripts/live-browser.js b/.pi/skills/impeccable/scripts/live-browser.js index cc1b5bd4f..d4de79ece 100644 --- a/.pi/skills/impeccable/scripts/live-browser.js +++ b/.pi/skills/impeccable/scripts/live-browser.js @@ -2135,6 +2135,15 @@ void main() { function saveSession() { if (!currentSessionId) return; + // Capture the selected element's current viewport-relative top so we + // can restore the same framing after a reload, even if layout shifts. + let scrollAnchor = null; + try { + if (selectedElement && selectedElement.isConnected) { + const r = selectedElement.getBoundingClientRect(); + if (r.width > 0 && r.height > 0) scrollAnchor = { viewportTop: r.top }; + } + } catch {} try { localStorage.setItem(LS_KEY, JSON.stringify({ id: currentSessionId, @@ -2144,6 +2153,7 @@ void main() { expected: expectedVariants, arrived: arrivedVariants, visible: visibleVariant, + scrollAnchor, })); } catch { /* quota exceeded or private mode */ } } @@ -2288,6 +2298,25 @@ void main() { // Set display state BEFORE starting observer (avoid triggering it) if (visibleVariant > 0) showVariantInDOM(currentSessionId, visibleVariant); + // Restore scroll: land the selected element back at the same + // viewport-relative top it had before the reload. Two passes — once + // synchronously, once after fonts/images settle — catch late layout + // shifts without animating the correction. + if (saved?.scrollAnchor && selectedElement) { + try { history.scrollRestoration = 'manual'; } catch {} + const targetTop = saved.scrollAnchor.viewportTop; + const correct = () => { + if (!selectedElement?.isConnected) return; + const delta = selectedElement.getBoundingClientRect().top - targetTop; + if (Math.abs(delta) > 0.5) window.scrollBy({ top: delta, left: 0, behavior: 'instant' }); + }; + correct(); + requestAnimationFrame(() => requestAnimationFrame(correct)); + if (document.fonts?.ready) { + document.fonts.ready.then(() => requestAnimationFrame(correct)).catch(() => {}); + } + } + state = arrivedVariants >= expectedVariants ? 'CYCLING' : 'GENERATING'; showBar(state === 'CYCLING' ? 'cycling' : 'generating'); startScrollTracking(); diff --git a/.rovodev/skills/impeccable/scripts/live-browser.js b/.rovodev/skills/impeccable/scripts/live-browser.js index cc1b5bd4f..d4de79ece 100644 --- a/.rovodev/skills/impeccable/scripts/live-browser.js +++ b/.rovodev/skills/impeccable/scripts/live-browser.js @@ -2135,6 +2135,15 @@ void main() { function saveSession() { if (!currentSessionId) return; + // Capture the selected element's current viewport-relative top so we + // can restore the same framing after a reload, even if layout shifts. + let scrollAnchor = null; + try { + if (selectedElement && selectedElement.isConnected) { + const r = selectedElement.getBoundingClientRect(); + if (r.width > 0 && r.height > 0) scrollAnchor = { viewportTop: r.top }; + } + } catch {} try { localStorage.setItem(LS_KEY, JSON.stringify({ id: currentSessionId, @@ -2144,6 +2153,7 @@ void main() { expected: expectedVariants, arrived: arrivedVariants, visible: visibleVariant, + scrollAnchor, })); } catch { /* quota exceeded or private mode */ } } @@ -2288,6 +2298,25 @@ void main() { // Set display state BEFORE starting observer (avoid triggering it) if (visibleVariant > 0) showVariantInDOM(currentSessionId, visibleVariant); + // Restore scroll: land the selected element back at the same + // viewport-relative top it had before the reload. Two passes — once + // synchronously, once after fonts/images settle — catch late layout + // shifts without animating the correction. + if (saved?.scrollAnchor && selectedElement) { + try { history.scrollRestoration = 'manual'; } catch {} + const targetTop = saved.scrollAnchor.viewportTop; + const correct = () => { + if (!selectedElement?.isConnected) return; + const delta = selectedElement.getBoundingClientRect().top - targetTop; + if (Math.abs(delta) > 0.5) window.scrollBy({ top: delta, left: 0, behavior: 'instant' }); + }; + correct(); + requestAnimationFrame(() => requestAnimationFrame(correct)); + if (document.fonts?.ready) { + document.fonts.ready.then(() => requestAnimationFrame(correct)).catch(() => {}); + } + } + state = arrivedVariants >= expectedVariants ? 'CYCLING' : 'GENERATING'; showBar(state === 'CYCLING' ? 'cycling' : 'generating'); startScrollTracking(); diff --git a/.trae-cn/skills/impeccable/scripts/live-browser.js b/.trae-cn/skills/impeccable/scripts/live-browser.js index cc1b5bd4f..d4de79ece 100644 --- a/.trae-cn/skills/impeccable/scripts/live-browser.js +++ b/.trae-cn/skills/impeccable/scripts/live-browser.js @@ -2135,6 +2135,15 @@ void main() { function saveSession() { if (!currentSessionId) return; + // Capture the selected element's current viewport-relative top so we + // can restore the same framing after a reload, even if layout shifts. + let scrollAnchor = null; + try { + if (selectedElement && selectedElement.isConnected) { + const r = selectedElement.getBoundingClientRect(); + if (r.width > 0 && r.height > 0) scrollAnchor = { viewportTop: r.top }; + } + } catch {} try { localStorage.setItem(LS_KEY, JSON.stringify({ id: currentSessionId, @@ -2144,6 +2153,7 @@ void main() { expected: expectedVariants, arrived: arrivedVariants, visible: visibleVariant, + scrollAnchor, })); } catch { /* quota exceeded or private mode */ } } @@ -2288,6 +2298,25 @@ void main() { // Set display state BEFORE starting observer (avoid triggering it) if (visibleVariant > 0) showVariantInDOM(currentSessionId, visibleVariant); + // Restore scroll: land the selected element back at the same + // viewport-relative top it had before the reload. Two passes — once + // synchronously, once after fonts/images settle — catch late layout + // shifts without animating the correction. + if (saved?.scrollAnchor && selectedElement) { + try { history.scrollRestoration = 'manual'; } catch {} + const targetTop = saved.scrollAnchor.viewportTop; + const correct = () => { + if (!selectedElement?.isConnected) return; + const delta = selectedElement.getBoundingClientRect().top - targetTop; + if (Math.abs(delta) > 0.5) window.scrollBy({ top: delta, left: 0, behavior: 'instant' }); + }; + correct(); + requestAnimationFrame(() => requestAnimationFrame(correct)); + if (document.fonts?.ready) { + document.fonts.ready.then(() => requestAnimationFrame(correct)).catch(() => {}); + } + } + state = arrivedVariants >= expectedVariants ? 'CYCLING' : 'GENERATING'; showBar(state === 'CYCLING' ? 'cycling' : 'generating'); startScrollTracking(); diff --git a/.trae/skills/impeccable/scripts/live-browser.js b/.trae/skills/impeccable/scripts/live-browser.js index cc1b5bd4f..d4de79ece 100644 --- a/.trae/skills/impeccable/scripts/live-browser.js +++ b/.trae/skills/impeccable/scripts/live-browser.js @@ -2135,6 +2135,15 @@ void main() { function saveSession() { if (!currentSessionId) return; + // Capture the selected element's current viewport-relative top so we + // can restore the same framing after a reload, even if layout shifts. + let scrollAnchor = null; + try { + if (selectedElement && selectedElement.isConnected) { + const r = selectedElement.getBoundingClientRect(); + if (r.width > 0 && r.height > 0) scrollAnchor = { viewportTop: r.top }; + } + } catch {} try { localStorage.setItem(LS_KEY, JSON.stringify({ id: currentSessionId, @@ -2144,6 +2153,7 @@ void main() { expected: expectedVariants, arrived: arrivedVariants, visible: visibleVariant, + scrollAnchor, })); } catch { /* quota exceeded or private mode */ } } @@ -2288,6 +2298,25 @@ void main() { // Set display state BEFORE starting observer (avoid triggering it) if (visibleVariant > 0) showVariantInDOM(currentSessionId, visibleVariant); + // Restore scroll: land the selected element back at the same + // viewport-relative top it had before the reload. Two passes — once + // synchronously, once after fonts/images settle — catch late layout + // shifts without animating the correction. + if (saved?.scrollAnchor && selectedElement) { + try { history.scrollRestoration = 'manual'; } catch {} + const targetTop = saved.scrollAnchor.viewportTop; + const correct = () => { + if (!selectedElement?.isConnected) return; + const delta = selectedElement.getBoundingClientRect().top - targetTop; + if (Math.abs(delta) > 0.5) window.scrollBy({ top: delta, left: 0, behavior: 'instant' }); + }; + correct(); + requestAnimationFrame(() => requestAnimationFrame(correct)); + if (document.fonts?.ready) { + document.fonts.ready.then(() => requestAnimationFrame(correct)).catch(() => {}); + } + } + state = arrivedVariants >= expectedVariants ? 'CYCLING' : 'GENERATING'; showBar(state === 'CYCLING' ? 'cycling' : 'generating'); startScrollTracking(); diff --git a/public/index.html b/public/index.html index f693bee2d..49dfd5d31 100644 --- a/public/index.html +++ b/public/index.html @@ -104,6 +104,8 @@
Impeccable is built by Renaissance Geek. I work with enterprise teams on large-scale rollouts, custom integrations, and training for designers and developers. If you're a frontier lab, design tool company, or enterprise looking to raise the bar on AI-generated design, let's talk.
+Impeccable is built by Renaissance Geek. I work with enterprise teams on large-scale rollouts, custom integrations, and training for designers and developers. If you're a frontier lab, design tool company, or enterprise looking to raise the bar on AI-generated design, let's talk.