@foldkit/devtools 0.136.0 → 0.138.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
- export declare const overlayStyles = ":host {\n position: relative;\n z-index: 2147483647;\n\n --dt-bg: #1e1e2e;\n --dt-surface-selected: #282839;\n --dt-border: #45475a;\n --dt-text: #cdd6f4;\n --dt-text-muted: #9399b2;\n --dt-accent: #cba6f7;\n --dt-live: #a6e3a1;\n --dt-paused: #fab387;\n --dt-json-string: #a6e3a1;\n --dt-json-number: #89b4fa;\n --dt-json-boolean: #fab387;\n --dt-json-null: #9399b2;\n --dt-json-key: #89dceb;\n --dt-json-tag: #cba6f7;\n --dt-json-preview: #9399b2;\n --dt-json-arrow: #9399b2;\n --dt-tree-hover: #313244;\n --dt-diff-changed: #74c7ec;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n}\nbutton {\n font: inherit;\n color: inherit;\n}\nul {\n list-style: none;\n}\n\n.fixed {\n position: fixed;\n}\n.flex {\n display: flex;\n}\n.contents {\n display: contents;\n}\n.flex-col {\n flex-direction: column;\n}\n.flex-1 {\n flex: 1 1 0%;\n}\n.items-center {\n align-items: center;\n}\n.justify-center {\n justify-content: center;\n}\n.justify-between {\n justify-content: space-between;\n}\n.shrink-0 {\n flex-shrink: 0;\n}\n.inline-block {\n display: inline-block;\n}\n.gap-0\\.5 {\n gap: 2px;\n}\n.gap-1\\.5 {\n gap: 6px;\n}\n.gap-2 {\n gap: 8px;\n}\n.gap-3 {\n gap: 12px;\n}\n.gap-px {\n gap: 1px;\n}\n.px-1 {\n padding-left: 4px;\n padding-right: 4px;\n}\n.px-2 {\n padding-left: 8px;\n padding-right: 8px;\n}\n.px-2\\.5 {\n padding-left: 10px;\n padding-right: 10px;\n}\n.p-3 {\n padding: 12px;\n}\n.px-3 {\n padding-left: 12px;\n padding-right: 12px;\n}\n.py-0\\.5 {\n padding-top: 2px;\n padding-bottom: 2px;\n}\n.pt-1 {\n padding-top: 4px;\n}\n.pl-1 {\n padding-left: 4px;\n}\n.py-1 {\n padding-top: 4px;\n padding-bottom: 4px;\n}\n.py-1\\.5 {\n padding-top: 6px;\n padding-bottom: 6px;\n}\n.py-2 {\n padding-top: 8px;\n padding-bottom: 8px;\n}\n.py-px {\n padding-top: 1px;\n padding-bottom: 1px;\n}\n.w-1\\.5 {\n width: 6px;\n}\n.h-1\\.5 {\n height: 6px;\n}\n.w-3 {\n width: 12px;\n}\n.w-5 {\n width: 20px;\n}\n.h-5 {\n height: 20px;\n}\n.w-14 {\n width: 56px;\n}\n.h-14 {\n height: 56px;\n}\n.min-w-0 {\n min-width: 0;\n}\n.min-w-5 {\n min-width: 20px;\n}\n.min-h-0 {\n min-height: 0;\n}\n/* Badge positions \u2014 flush against side edge */\n.dt-pos-br {\n bottom: 16px;\n right: 0;\n border-radius: 6px 0 0 6px;\n}\n.dt-pos-bl {\n bottom: 16px;\n left: 0;\n border-radius: 0 6px 6px 0;\n}\n.dt-pos-tr {\n top: 16px;\n right: 0;\n border-radius: 6px 0 0 6px;\n}\n.dt-pos-tl {\n top: 16px;\n left: 0;\n border-radius: 0 6px 6px 0;\n}\n.overflow-hidden {\n overflow: hidden;\n}\n.overflow-auto {\n overflow: auto;\n}\n.overflow-y-auto {\n overflow-y: auto;\n}\n.overscroll-none {\n overscroll-behavior: none;\n}\n\n.truncate {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.rounded {\n border-radius: 4px;\n}\n.rounded-lg {\n border-radius: 8px;\n}\n.rounded-full {\n border-radius: 9999px;\n}\n.border {\n border-width: 1px;\n border-style: solid;\n border-color: var(--dt-border);\n}\n.border-b {\n border-bottom: 1px solid var(--dt-border);\n}\n.border-t {\n border-top: 1px solid var(--dt-border);\n}\n.border-r {\n border-right: 1px solid var(--dt-border);\n}\n.border-l {\n border-left: 1px solid var(--dt-border);\n}\n.border-none {\n border: none;\n}\n.selected {\n background-color: var(--dt-surface-selected);\n}\n.dt-row:hover:not(.selected) {\n background-color: var(--dt-tree-hover);\n}\n.dt-header-button:hover {\n color: var(--dt-text);\n}\n.dt-resume-button:hover {\n opacity: 0.7;\n}\n.dt-scroll-pill {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n flex-shrink: 0;\n padding: 4px 12px;\n background-color: var(--dt-surface-selected);\n border: none;\n border-bottom: 1px solid var(--dt-border);\n color: var(--dt-accent);\n font-family:\n ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;\n font-size: 13px;\n cursor: pointer;\n}\n.dt-scroll-pill-icon {\n width: 12px;\n height: 12px;\n}\n.dt-scroll-pill-text {\n margin-top: 1px;\n}\n.dt-scroll-pill:hover {\n background-color: var(--dt-tree-hover);\n}\n.dt-scroll-pill:focus-visible {\n outline: 1px solid var(--dt-accent);\n outline-offset: -1px;\n}\n.dt-filter-wrapper {\n position: relative;\n flex-shrink: 0;\n border-bottom: 1px solid var(--dt-border);\n}\n.dt-filter-button {\n width: 100%;\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 6px 12px;\n background: transparent;\n border: none;\n color: var(--dt-text-muted);\n font-family:\n ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;\n font-size: 13px;\n cursor: pointer;\n text-align: left;\n}\n.dt-filter-button:hover {\n color: var(--dt-text);\n background-color: var(--dt-tree-hover);\n}\n.dt-filter-button:focus-visible {\n outline: 1px solid var(--dt-accent);\n outline-offset: -1px;\n}\n.dt-filter-button[data-open] {\n color: var(--dt-text);\n background-color: var(--dt-surface-selected);\n}\n.dt-filter-button[data-open]:hover {\n background-color: var(--dt-tree-hover);\n}\n.dt-filter-button[data-open] .json-arrow {\n transform: rotate(180deg);\n}\n.dt-filter-items {\n position: absolute;\n width: var(--button-width);\n background-color: var(--dt-bg);\n border-top: 1px solid var(--dt-border);\n border-bottom: 1px solid var(--dt-border);\n z-index: 100000;\n max-height: 200px;\n overflow-y: auto;\n outline: none;\n}\n.dt-filter-item {\n padding: 6px 12px;\n color: var(--dt-text-muted);\n cursor: pointer;\n font-family:\n ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;\n font-size: 13px;\n border-bottom: 1px solid var(--dt-border);\n}\n.dt-filter-item:last-child {\n border-bottom: none;\n}\n.dt-filter-item[data-active] {\n background-color: var(--dt-tree-hover);\n color: var(--dt-text);\n}\n.dt-filter-item[data-selected] {\n color: var(--dt-accent);\n}\n.dt-filter-check {\n width: 12px;\n height: 12px;\n visibility: hidden;\n}\n.dt-filter-item[data-selected] .dt-filter-check {\n visibility: visible;\n color: var(--dt-accent);\n}\n.dt-filter-backdrop {\n position: fixed;\n inset: 0;\n pointer-events: none;\n}\n.dt-settings-button {\n display: flex;\n align-items: center;\n justify-content: center;\n align-self: stretch;\n margin: -8px 0 -8px -12px;\n padding: 0 12px;\n background: transparent;\n border: none;\n border-right: 1px solid var(--dt-border);\n color: var(--dt-text-muted);\n cursor: pointer;\n flex-shrink: 0;\n}\n.dt-settings-button:hover {\n color: var(--dt-text);\n background-color: var(--dt-tree-hover);\n}\n.dt-settings-button:focus-visible {\n outline: 1px solid var(--dt-accent);\n outline-offset: -1px;\n}\n.dt-settings-button-active {\n color: var(--dt-accent);\n background-color: var(--dt-surface-selected);\n}\n.dt-settings-button-active:hover {\n background-color: var(--dt-tree-hover);\n}\n.dt-settings-icon {\n width: 14px;\n height: 14px;\n}\n.dt-settings-section-title {\n padding: 10px 12px 4px;\n color: var(--dt-text-muted);\n font-size: 10px;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n}\n.dt-settings-row {\n display: flex;\n align-items: center;\n gap: 20px;\n padding: 8px 12px;\n}\n.dt-settings-row-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n.dt-settings-row-label {\n color: var(--dt-text);\n font-size: 13px;\n cursor: pointer;\n}\n.dt-settings-row-description {\n color: var(--dt-text-muted);\n font-size: 10px;\n}\n.dt-switch {\n position: relative;\n width: 36px;\n height: 20px;\n border-radius: 9999px;\n background-color: var(--dt-border);\n cursor: pointer;\n flex-shrink: 0;\n transition:\n background-color 100ms ease,\n filter 100ms ease;\n}\n.dt-switch:hover {\n filter: brightness(1.2);\n}\n.dt-switch:focus-visible {\n outline: 1px solid var(--dt-accent);\n outline-offset: 2px;\n}\n.dt-switch[data-checked] {\n background-color: var(--dt-accent);\n}\n.dt-switch-thumb {\n position: absolute;\n top: 2px;\n left: 2px;\n width: 16px;\n height: 16px;\n border-radius: 9999px;\n background-color: var(--dt-text-muted);\n transition:\n transform 100ms ease,\n background-color 100ms ease;\n}\n.dt-switch[data-checked] .dt-switch-thumb {\n transform: translateX(16px);\n background-color: var(--dt-bg);\n}\n.dt-tab-button {\n position: relative;\n background: transparent;\n border: none;\n border-right: 1px solid var(--dt-border);\n outline: none;\n flex: 1;\n}\n.dt-tab-button:last-child {\n border-right: none;\n}\n.dt-tab-active {\n background-color: var(--dt-surface-selected);\n}\n.dt-tab-button:not(.dt-tab-active):hover {\n color: var(--dt-text);\n background-color: rgba(49, 50, 68, 0.3);\n}\n.font-sans {\n font-family:\n system-ui,\n -apple-system,\n BlinkMacSystemFont,\n 'Segoe UI',\n Roboto,\n sans-serif;\n}\n.font-mono {\n font-family:\n ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;\n}\n.font-medium {\n font-weight: 500;\n}\n.font-semibold {\n font-weight: 600;\n}\n.text-xs {\n font-size: 12px;\n}\n.text-2xs {\n font-size: 10px;\n}\n.text-sm {\n font-size: 11px;\n}\n.text-base {\n font-size: 13px;\n}\n.text-md {\n font-size: 15px;\n}\n.text-lg {\n font-size: 20px;\n}\n.text-xl {\n font-size: 26px;\n}\n.italic {\n font-style: italic;\n}\n.text-right {\n text-align: right;\n}\n.tracking-wide {\n letter-spacing: 0.025em;\n}\n.tracking-wider {\n letter-spacing: 0.05em;\n}\n.leading-none {\n line-height: 1;\n}\n.leading-snug {\n line-height: 1.35;\n}\n.bg-dt-bg {\n background-color: var(--dt-bg);\n}\n.bg-dt-live {\n background-color: var(--dt-live);\n}\n.bg-transparent {\n background-color: transparent;\n}\n.text-dt {\n color: var(--dt-text);\n}\n.text-dt-bg {\n color: var(--dt-bg);\n}\n.text-dt-muted {\n color: var(--dt-text-muted);\n}\n.text-dt-accent {\n color: var(--dt-accent);\n}\n.text-dt-live {\n color: var(--dt-live);\n}\n.text-dt-paused {\n color: var(--dt-paused);\n}\n.cursor-pointer {\n cursor: pointer;\n}\n.outline-none {\n outline: none;\n}\n.transition-colors {\n transition-property: color, background-color, border-color;\n transition-duration: 100ms;\n transition-timing-function: ease;\n}\n\n/* Panel */\n.dt-panel {\n width: 360px;\n height: 480px;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);\n z-index: 99998;\n}\n/* Panel positions */\n.dt-panel-br {\n bottom: 16px;\n right: 28px;\n}\n.dt-panel-bl {\n bottom: 16px;\n left: 28px;\n}\n.dt-panel-tr {\n top: 16px;\n right: 28px;\n}\n.dt-panel-tl {\n top: 16px;\n left: 28px;\n}\n.dt-panel-wide {\n width: 720px;\n}\n.dt-message-pane {\n width: 320px;\n flex-shrink: 0;\n}\n.dt-badge {\n z-index: 99999;\n box-shadow: -2px 0 8px rgba(0, 0, 0, 0.3);\n transition: background-color 150ms ease;\n border: 1px solid var(--dt-border);\n}\n.dt-badge-accent:hover {\n background-color: #252538;\n}\n.dt-badge-paused {\n background-color: var(--dt-paused);\n color: var(--dt-bg);\n border: none;\n}\n.dt-badge-paused:hover {\n background-color: #e0a070;\n}\n.dt-badge.dt-pos-br,\n.dt-badge.dt-pos-tr {\n border-right: none;\n}\n.dt-badge.dt-pos-bl,\n.dt-badge.dt-pos-tl {\n border-left: none;\n}\n\n/* JSON tree */\n.tree-row {\n position: relative;\n white-space: nowrap;\n line-height: 18px;\n padding-right: 8px;\n}\n.tree-row-expandable:hover {\n background-color: var(--dt-tree-hover);\n}\n.inspector-tree {\n font-family:\n ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;\n}\n.json-key {\n color: var(--dt-json-key);\n}\n.json-string {\n color: var(--dt-json-string);\n}\n.json-number {\n color: var(--dt-json-number);\n}\n.json-boolean {\n color: var(--dt-json-boolean);\n}\n.json-null {\n color: var(--dt-json-null);\n}\n.json-tag {\n color: var(--dt-json-tag);\n margin-right: 4px;\n}\n.json-preview {\n color: var(--dt-json-preview);\n}\n.json-arrow {\n color: var(--dt-json-arrow);\n width: 10px;\n height: 10px;\n user-select: none;\n}\n\n/* Diff */\n.diff-changed {\n background-color: rgba(116, 199, 236, 0.06);\n}\n.diff-dot {\n position: absolute;\n left: 3px;\n width: 5px;\n height: 5px;\n border-radius: 9999px;\n background-color: var(--dt-diff-changed);\n}\n.diff-dot-inline {\n width: 5px;\n height: 5px;\n border-radius: 9999px;\n background-color: var(--dt-diff-changed);\n flex-shrink: 0;\n}\n.dot-column {\n width: 5px;\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.pause-column {\n width: 8px;\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.dt-pause-icon {\n width: 8px;\n height: 8px;\n color: var(--dt-paused);\n}\n\n/* Interaction blocker \u2014 covers the app while time-travelling */\n.dt-interaction-blocker {\n position: fixed;\n inset: 0;\n z-index: 99997;\n cursor: not-allowed;\n}\n\n/* Footer */\n.dt-footer {\n background-color: var(--dt-bg);\n height: 33px;\n}\n\n/* Scrubber */\n.dt-scrubber-control {\n position: relative;\n height: 16px;\n width: 100%;\n padding: 0 7px;\n display: flex;\n align-items: center;\n}\n.dt-scrubber-track {\n width: 100%;\n height: 4px;\n background-color: var(--dt-border);\n border-radius: 9999px;\n cursor: pointer;\n}\n.dt-scrubber-track[data-disabled] {\n cursor: not-allowed;\n}\n.dt-scrubber-fill {\n height: 100%;\n background-color: var(--dt-accent);\n border-radius: 9999px;\n}\n.dt-scrubber-thumb {\n width: 14px;\n height: 14px;\n border-radius: 9999px;\n background-color: var(--dt-accent);\n border: 2px solid var(--dt-bg);\n cursor: grab;\n outline: none;\n top: 50%;\n margin-top: -7px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);\n}\n.dt-scrubber-thumb:focus-visible {\n outline: 2px solid var(--dt-text);\n outline-offset: 2px;\n}\n.dt-scrubber-thumb[data-dragging] {\n cursor: grabbing;\n}\n.dt-scrubber-position {\n width: 72px;\n padding-left: 12px;\n border-left: 1px solid var(--dt-border);\n align-self: stretch;\n margin-top: -8px;\n margin-bottom: -8px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n/* Mobile */\n@media (max-width: 767px) {\n .dt-panel {\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n width: 100%;\n height: 100%;\n border-radius: 0;\n border: none;\n }\n .dt-panel-wide {\n width: 100%;\n }\n .dt-content {\n flex-direction: column;\n }\n .dt-message-pane {\n width: 100%;\n max-height: 40%;\n border-bottom: 1px solid var(--dt-border);\n }\n .message-list > :last-child {\n border-bottom: none;\n }\n .dt-inspector-pane {\n border-left: none;\n }\n .dt-badge.dt-pos-br,\n .dt-badge.dt-pos-bl {\n bottom: 44px;\n }\n}\n";
1
+ export declare const overlayStyles = ":host {\n /* The host spans the viewport so it has real bounds to snapshot: it carries a\n `view-transition-name` (set in `overlay.ts`, see the note there) to stay\n out of an application's View Transitions, and a name on a zero-size element\n captures nothing. The box itself is inert; the panels inside opt back into\n hit-testing through `.fixed`. */\n position: fixed;\n inset: 0;\n pointer-events: none;\n z-index: 2147483647;\n\n --dt-bg: #1e1e2e;\n --dt-surface-selected: #282839;\n --dt-border: #45475a;\n --dt-text: #cdd6f4;\n --dt-text-muted: #9399b2;\n --dt-accent: #cba6f7;\n --dt-live: #a6e3a1;\n --dt-paused: #fab387;\n --dt-json-string: #a6e3a1;\n --dt-json-number: #89b4fa;\n --dt-json-boolean: #fab387;\n --dt-json-null: #9399b2;\n --dt-json-key: #89dceb;\n --dt-json-tag: #cba6f7;\n --dt-json-preview: #9399b2;\n --dt-json-arrow: #9399b2;\n --dt-tree-hover: #313244;\n --dt-diff-changed: #74c7ec;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n}\nbutton {\n font: inherit;\n color: inherit;\n}\nul {\n list-style: none;\n}\n\n/* The host is `pointer-events: none` so its viewport-spanning box cannot\n swallow clicks meant for the application, and everything the shadow root\n renders opts back in here. The boundary is the shadow root's children rather\n than any one panel class: content arrives by routes a class list does not\n cover, including the portal root `@foldkit/ui` prepends for anchored\n dropdowns, and a surface that misses the opt-in is silently unclickable.\n These wrappers are zero-height, so granting them hit-testing costs nothing;\n descendants that must stay transparent, like the listbox backdrop, set\n `pointer-events: none` on themselves. */\n:host > * {\n pointer-events: auto;\n}\n\n.fixed {\n position: fixed;\n}\n.flex {\n display: flex;\n}\n.contents {\n display: contents;\n}\n.flex-col {\n flex-direction: column;\n}\n.flex-1 {\n flex: 1 1 0%;\n}\n.items-center {\n align-items: center;\n}\n.justify-center {\n justify-content: center;\n}\n.justify-between {\n justify-content: space-between;\n}\n.shrink-0 {\n flex-shrink: 0;\n}\n.inline-block {\n display: inline-block;\n}\n.gap-0\\.5 {\n gap: 2px;\n}\n.gap-1\\.5 {\n gap: 6px;\n}\n.gap-2 {\n gap: 8px;\n}\n.gap-3 {\n gap: 12px;\n}\n.gap-px {\n gap: 1px;\n}\n.px-1 {\n padding-left: 4px;\n padding-right: 4px;\n}\n.px-2 {\n padding-left: 8px;\n padding-right: 8px;\n}\n.px-2\\.5 {\n padding-left: 10px;\n padding-right: 10px;\n}\n.p-3 {\n padding: 12px;\n}\n.px-3 {\n padding-left: 12px;\n padding-right: 12px;\n}\n.py-0\\.5 {\n padding-top: 2px;\n padding-bottom: 2px;\n}\n.pt-1 {\n padding-top: 4px;\n}\n.pl-1 {\n padding-left: 4px;\n}\n.py-1 {\n padding-top: 4px;\n padding-bottom: 4px;\n}\n.py-1\\.5 {\n padding-top: 6px;\n padding-bottom: 6px;\n}\n.py-2 {\n padding-top: 8px;\n padding-bottom: 8px;\n}\n.py-px {\n padding-top: 1px;\n padding-bottom: 1px;\n}\n.w-1\\.5 {\n width: 6px;\n}\n.h-1\\.5 {\n height: 6px;\n}\n.w-3 {\n width: 12px;\n}\n.w-5 {\n width: 20px;\n}\n.h-5 {\n height: 20px;\n}\n.w-14 {\n width: 56px;\n}\n.h-14 {\n height: 56px;\n}\n.min-w-0 {\n min-width: 0;\n}\n.min-w-5 {\n min-width: 20px;\n}\n.min-h-0 {\n min-height: 0;\n}\n/* Badge positions \u2014 flush against side edge */\n.dt-pos-br {\n bottom: 16px;\n right: 0;\n border-radius: 6px 0 0 6px;\n}\n.dt-pos-bl {\n bottom: 16px;\n left: 0;\n border-radius: 0 6px 6px 0;\n}\n.dt-pos-tr {\n top: 16px;\n right: 0;\n border-radius: 6px 0 0 6px;\n}\n.dt-pos-tl {\n top: 16px;\n left: 0;\n border-radius: 0 6px 6px 0;\n}\n.overflow-hidden {\n overflow: hidden;\n}\n.overflow-auto {\n overflow: auto;\n}\n.overflow-y-auto {\n overflow-y: auto;\n}\n.overscroll-none {\n overscroll-behavior: none;\n}\n\n.truncate {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.rounded {\n border-radius: 4px;\n}\n.rounded-lg {\n border-radius: 8px;\n}\n.rounded-full {\n border-radius: 9999px;\n}\n.border {\n border-width: 1px;\n border-style: solid;\n border-color: var(--dt-border);\n}\n.border-b {\n border-bottom: 1px solid var(--dt-border);\n}\n.border-t {\n border-top: 1px solid var(--dt-border);\n}\n.border-r {\n border-right: 1px solid var(--dt-border);\n}\n.border-l {\n border-left: 1px solid var(--dt-border);\n}\n.border-none {\n border: none;\n}\n.selected {\n background-color: var(--dt-surface-selected);\n}\n.dt-row:hover:not(.selected) {\n background-color: var(--dt-tree-hover);\n}\n.dt-header-button:hover {\n color: var(--dt-text);\n}\n.dt-resume-button:hover {\n opacity: 0.7;\n}\n.dt-scroll-pill {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n flex-shrink: 0;\n padding: 4px 12px;\n background-color: var(--dt-surface-selected);\n border: none;\n border-bottom: 1px solid var(--dt-border);\n color: var(--dt-accent);\n font-family:\n ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;\n font-size: 13px;\n cursor: pointer;\n}\n.dt-scroll-pill-icon {\n width: 12px;\n height: 12px;\n}\n.dt-scroll-pill-text {\n margin-top: 1px;\n}\n.dt-scroll-pill:hover {\n background-color: var(--dt-tree-hover);\n}\n.dt-scroll-pill:focus-visible {\n outline: 1px solid var(--dt-accent);\n outline-offset: -1px;\n}\n.dt-filter-wrapper {\n position: relative;\n flex-shrink: 0;\n border-bottom: 1px solid var(--dt-border);\n}\n.dt-filter-button {\n width: 100%;\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 6px 12px;\n background: transparent;\n border: none;\n color: var(--dt-text-muted);\n font-family:\n ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;\n font-size: 13px;\n cursor: pointer;\n text-align: left;\n}\n.dt-filter-button:hover {\n color: var(--dt-text);\n background-color: var(--dt-tree-hover);\n}\n.dt-filter-button:focus-visible {\n outline: 1px solid var(--dt-accent);\n outline-offset: -1px;\n}\n.dt-filter-button[data-open] {\n color: var(--dt-text);\n background-color: var(--dt-surface-selected);\n}\n.dt-filter-button[data-open]:hover {\n background-color: var(--dt-tree-hover);\n}\n.dt-filter-button[data-open] .json-arrow {\n transform: rotate(180deg);\n}\n.dt-filter-items {\n position: absolute;\n width: var(--button-width);\n background-color: var(--dt-bg);\n border-top: 1px solid var(--dt-border);\n border-bottom: 1px solid var(--dt-border);\n z-index: 100000;\n max-height: 200px;\n overflow-y: auto;\n outline: none;\n}\n.dt-filter-item {\n padding: 6px 12px;\n color: var(--dt-text-muted);\n cursor: pointer;\n font-family:\n ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;\n font-size: 13px;\n border-bottom: 1px solid var(--dt-border);\n}\n.dt-filter-item:last-child {\n border-bottom: none;\n}\n.dt-filter-item[data-active] {\n background-color: var(--dt-tree-hover);\n color: var(--dt-text);\n}\n.dt-filter-item[data-selected] {\n color: var(--dt-accent);\n}\n.dt-filter-check {\n width: 12px;\n height: 12px;\n visibility: hidden;\n}\n.dt-filter-item[data-selected] .dt-filter-check {\n visibility: visible;\n color: var(--dt-accent);\n}\n.dt-filter-backdrop {\n position: fixed;\n inset: 0;\n pointer-events: none;\n}\n.dt-settings-button {\n display: flex;\n align-items: center;\n justify-content: center;\n align-self: stretch;\n margin: -8px 0 -8px -12px;\n padding: 0 12px;\n background: transparent;\n border: none;\n border-right: 1px solid var(--dt-border);\n color: var(--dt-text-muted);\n cursor: pointer;\n flex-shrink: 0;\n}\n.dt-settings-button:hover {\n color: var(--dt-text);\n background-color: var(--dt-tree-hover);\n}\n.dt-settings-button:focus-visible {\n outline: 1px solid var(--dt-accent);\n outline-offset: -1px;\n}\n.dt-settings-button-active {\n color: var(--dt-accent);\n background-color: var(--dt-surface-selected);\n}\n.dt-settings-button-active:hover {\n background-color: var(--dt-tree-hover);\n}\n.dt-settings-icon {\n width: 14px;\n height: 14px;\n}\n.dt-settings-section-title {\n padding: 10px 12px 4px;\n color: var(--dt-text-muted);\n font-size: 10px;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n}\n.dt-settings-row {\n display: flex;\n align-items: center;\n gap: 20px;\n padding: 8px 12px;\n}\n.dt-settings-row-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n.dt-settings-row-label {\n color: var(--dt-text);\n font-size: 13px;\n cursor: pointer;\n}\n.dt-settings-row-description {\n color: var(--dt-text-muted);\n font-size: 10px;\n}\n.dt-switch {\n position: relative;\n width: 36px;\n height: 20px;\n border-radius: 9999px;\n background-color: var(--dt-border);\n cursor: pointer;\n flex-shrink: 0;\n transition:\n background-color 100ms ease,\n filter 100ms ease;\n}\n.dt-switch:hover {\n filter: brightness(1.2);\n}\n.dt-switch:focus-visible {\n outline: 1px solid var(--dt-accent);\n outline-offset: 2px;\n}\n.dt-switch[data-checked] {\n background-color: var(--dt-accent);\n}\n.dt-switch-thumb {\n position: absolute;\n top: 2px;\n left: 2px;\n width: 16px;\n height: 16px;\n border-radius: 9999px;\n background-color: var(--dt-text-muted);\n transition:\n transform 100ms ease,\n background-color 100ms ease;\n}\n.dt-switch[data-checked] .dt-switch-thumb {\n transform: translateX(16px);\n background-color: var(--dt-bg);\n}\n.dt-tab-button {\n position: relative;\n background: transparent;\n border: none;\n border-right: 1px solid var(--dt-border);\n outline: none;\n flex: 1;\n}\n.dt-tab-button:last-child {\n border-right: none;\n}\n.dt-tab-active {\n background-color: var(--dt-surface-selected);\n}\n.dt-tab-button:not(.dt-tab-active):hover {\n color: var(--dt-text);\n background-color: rgba(49, 50, 68, 0.3);\n}\n.font-sans {\n font-family:\n system-ui,\n -apple-system,\n BlinkMacSystemFont,\n 'Segoe UI',\n Roboto,\n sans-serif;\n}\n.font-mono {\n font-family:\n ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;\n}\n.font-medium {\n font-weight: 500;\n}\n.font-semibold {\n font-weight: 600;\n}\n.text-xs {\n font-size: 12px;\n}\n.text-2xs {\n font-size: 10px;\n}\n.text-sm {\n font-size: 11px;\n}\n.text-base {\n font-size: 13px;\n}\n.text-md {\n font-size: 15px;\n}\n.text-lg {\n font-size: 20px;\n}\n.text-xl {\n font-size: 26px;\n}\n.italic {\n font-style: italic;\n}\n.text-right {\n text-align: right;\n}\n.tracking-wide {\n letter-spacing: 0.025em;\n}\n.tracking-wider {\n letter-spacing: 0.05em;\n}\n.leading-none {\n line-height: 1;\n}\n.leading-snug {\n line-height: 1.35;\n}\n.bg-dt-bg {\n background-color: var(--dt-bg);\n}\n.bg-dt-live {\n background-color: var(--dt-live);\n}\n.bg-transparent {\n background-color: transparent;\n}\n.text-dt {\n color: var(--dt-text);\n}\n.text-dt-bg {\n color: var(--dt-bg);\n}\n.text-dt-muted {\n color: var(--dt-text-muted);\n}\n.text-dt-accent {\n color: var(--dt-accent);\n}\n.text-dt-live {\n color: var(--dt-live);\n}\n.text-dt-paused {\n color: var(--dt-paused);\n}\n.cursor-pointer {\n cursor: pointer;\n}\n.outline-none {\n outline: none;\n}\n.transition-colors {\n transition-property: color, background-color, border-color;\n transition-duration: 100ms;\n transition-timing-function: ease;\n}\n\n/* Panel */\n.dt-panel {\n width: 360px;\n height: 480px;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);\n z-index: 99998;\n}\n/* Panel positions */\n.dt-panel-br {\n bottom: 16px;\n right: 28px;\n}\n.dt-panel-bl {\n bottom: 16px;\n left: 28px;\n}\n.dt-panel-tr {\n top: 16px;\n right: 28px;\n}\n.dt-panel-tl {\n top: 16px;\n left: 28px;\n}\n.dt-panel-wide {\n width: 720px;\n}\n.dt-message-pane {\n width: 320px;\n flex-shrink: 0;\n}\n.dt-badge {\n z-index: 99999;\n box-shadow: -2px 0 8px rgba(0, 0, 0, 0.3);\n transition: background-color 150ms ease;\n border: 1px solid var(--dt-border);\n}\n.dt-badge-accent:hover {\n background-color: #252538;\n}\n.dt-badge-paused {\n background-color: var(--dt-paused);\n color: var(--dt-bg);\n border: none;\n}\n.dt-badge-paused:hover {\n background-color: #e0a070;\n}\n.dt-badge.dt-pos-br,\n.dt-badge.dt-pos-tr {\n border-right: none;\n}\n.dt-badge.dt-pos-bl,\n.dt-badge.dt-pos-tl {\n border-left: none;\n}\n\n/* JSON tree */\n.tree-row {\n position: relative;\n white-space: nowrap;\n line-height: 18px;\n padding-right: 8px;\n}\n.tree-row-expandable:hover {\n background-color: var(--dt-tree-hover);\n}\n.inspector-tree {\n font-family:\n ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;\n}\n.json-key {\n color: var(--dt-json-key);\n}\n.json-string {\n color: var(--dt-json-string);\n}\n.json-number {\n color: var(--dt-json-number);\n}\n.json-boolean {\n color: var(--dt-json-boolean);\n}\n.json-null {\n color: var(--dt-json-null);\n}\n.json-tag {\n color: var(--dt-json-tag);\n margin-right: 4px;\n}\n.json-preview {\n color: var(--dt-json-preview);\n}\n.json-arrow {\n color: var(--dt-json-arrow);\n width: 10px;\n height: 10px;\n user-select: none;\n}\n\n/* Diff */\n.diff-changed {\n background-color: rgba(116, 199, 236, 0.06);\n}\n.diff-dot {\n position: absolute;\n left: 3px;\n width: 5px;\n height: 5px;\n border-radius: 9999px;\n background-color: var(--dt-diff-changed);\n}\n.diff-dot-inline {\n width: 5px;\n height: 5px;\n border-radius: 9999px;\n background-color: var(--dt-diff-changed);\n flex-shrink: 0;\n}\n.dot-column {\n width: 5px;\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.pause-column {\n width: 8px;\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.dt-pause-icon {\n width: 8px;\n height: 8px;\n color: var(--dt-paused);\n}\n\n/* Interaction blocker \u2014 covers the app while time-travelling */\n.dt-interaction-blocker {\n position: fixed;\n inset: 0;\n z-index: 99997;\n cursor: not-allowed;\n}\n\n/* Footer */\n.dt-footer {\n background-color: var(--dt-bg);\n height: 33px;\n}\n\n/* Scrubber */\n.dt-scrubber-control {\n position: relative;\n height: 16px;\n width: 100%;\n padding: 0 7px;\n display: flex;\n align-items: center;\n}\n.dt-scrubber-track {\n width: 100%;\n height: 4px;\n background-color: var(--dt-border);\n border-radius: 9999px;\n cursor: pointer;\n}\n.dt-scrubber-track[data-disabled] {\n cursor: not-allowed;\n}\n.dt-scrubber-fill {\n height: 100%;\n background-color: var(--dt-accent);\n border-radius: 9999px;\n}\n.dt-scrubber-thumb {\n width: 14px;\n height: 14px;\n border-radius: 9999px;\n background-color: var(--dt-accent);\n border: 2px solid var(--dt-bg);\n cursor: grab;\n outline: none;\n top: 50%;\n margin-top: -7px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);\n}\n.dt-scrubber-thumb:focus-visible {\n outline: 2px solid var(--dt-text);\n outline-offset: 2px;\n}\n.dt-scrubber-thumb[data-dragging] {\n cursor: grabbing;\n}\n.dt-scrubber-position {\n width: 72px;\n padding-left: 12px;\n border-left: 1px solid var(--dt-border);\n align-self: stretch;\n margin-top: -8px;\n margin-bottom: -8px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n/* Mobile */\n@media (max-width: 767px) {\n .dt-panel {\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n width: 100%;\n height: 100%;\n border-radius: 0;\n border: none;\n }\n .dt-panel-wide {\n width: 100%;\n }\n .dt-content {\n flex-direction: column;\n }\n .dt-message-pane {\n width: 100%;\n max-height: 40%;\n border-bottom: 1px solid var(--dt-border);\n }\n .message-list > :last-child {\n border-bottom: none;\n }\n .dt-inspector-pane {\n border-left: none;\n }\n .dt-badge.dt-pos-br,\n .dt-badge.dt-pos-bl {\n bottom: 44px;\n }\n}\n";
2
2
  //# sourceMappingURL=overlay-styles.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"overlay-styles.d.ts","sourceRoot":"","sources":["../src/overlay-styles.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa,0gdAuyBzB,CAAA"}
1
+ {"version":3,"file":"overlay-styles.d.ts","sourceRoot":"","sources":["../src/overlay-styles.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa,wlfA2zBzB,CAAA"}
@@ -1,5 +1,12 @@
1
1
  export const overlayStyles = `:host {
2
- position: relative;
2
+ /* The host spans the viewport so it has real bounds to snapshot: it carries a
3
+ \`view-transition-name\` (set in \`overlay.ts\`, see the note there) to stay
4
+ out of an application's View Transitions, and a name on a zero-size element
5
+ captures nothing. The box itself is inert; the panels inside opt back into
6
+ hit-testing through \`.fixed\`. */
7
+ position: fixed;
8
+ inset: 0;
9
+ pointer-events: none;
3
10
  z-index: 2147483647;
4
11
 
5
12
  --dt-bg: #1e1e2e;
@@ -37,6 +44,19 @@ ul {
37
44
  list-style: none;
38
45
  }
39
46
 
47
+ /* The host is \`pointer-events: none\` so its viewport-spanning box cannot
48
+ swallow clicks meant for the application, and everything the shadow root
49
+ renders opts back in here. The boundary is the shadow root's children rather
50
+ than any one panel class: content arrives by routes a class list does not
51
+ cover, including the portal root \`@foldkit/ui\` prepends for anchored
52
+ dropdowns, and a surface that misses the opt-in is silently unclickable.
53
+ These wrappers are zero-height, so granting them hit-testing costs nothing;
54
+ descendants that must stay transparent, like the listbox backdrop, set
55
+ \`pointer-events: none\` on themselves. */
56
+ :host > * {
57
+ pointer-events: auto;
58
+ }
59
+
40
60
  .fixed {
41
61
  position: fixed;
42
62
  }
package/dist/overlay.d.ts CHANGED
@@ -26,10 +26,10 @@ declare const ShadowRootService_base: Context.ServiceClass<ShadowRootService, "f
26
26
  declare class ShadowRootService extends ShadowRootService_base {
27
27
  }
28
28
  export declare const LockScroll: Command.CommandDefinitionNoArgs<"LockScroll", Effect.Effect<{
29
- readonly _tag: "LockedScroll";
29
+ readonly _tag: "CompletedLockScroll";
30
30
  }, never, never>>;
31
31
  export declare const UnlockScroll: Command.CommandDefinitionNoArgs<"UnlockScroll", Effect.Effect<{
32
- readonly _tag: "UnlockedScroll";
32
+ readonly _tag: "CompletedUnlockScroll";
33
33
  }, never, never>>;
34
34
  export declare const PersistDevToolsState: Command.CommandDefinitionWithArgs<"PersistDevToolsState", {
35
35
  isOpen: S.Boolean;
@@ -69,7 +69,7 @@ export declare const Clear: Command.CommandDefinitionNoArgs<"Clear", Effect.Effe
69
69
  readonly _tag: "CompletedClear";
70
70
  }, never, StoreService>>;
71
71
  export declare const ScrollToTop: Command.CommandDefinitionNoArgs<"ScrollToTop", Effect.Effect<{
72
- readonly _tag: "ScrolledToTop";
72
+ readonly _tag: "CompletedScrollToTop";
73
73
  }, never, ShadowRootService>>;
74
74
  export declare const createOverlay: (store: DevToolsStore, position: DevToolsPosition, mode: DevToolsMode, maybeBanner: Option.Option<string>) => Effect.Effect<void, never, import("effect/Scope").Scope>;
75
75
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../src/overlay.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,OAAO,EACP,MAAM,EAEN,OAAO,EAGP,MAAM,EAKN,MAAM,IAAI,CAAC,EAGX,eAAe,EAEhB,MAAM,QAAQ,CAAA;AAEf,OAAO,KAAK,OAAO,MAAM,iBAAiB,CAAA;AAC1C,OAAO,EACL,KAAK,aAAa,EAElB,KAAK,aAAa,EAGlB,KAAK,WAAW,EAChB,KAAK,UAAU,EAKhB,MAAM,uBAAuB,CAAA;AAU9B,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;;oFAsDR,CAAC;;;;;;;;;;;;;;;;;AAkQ9D,cAAM,YAAa,SAAQ,iBAE1B;CAAG;;AAEJ,cAAM,iBAAkB,SAAQ,sBAGC;CAAG;AAEpC,eAAO,MAAM,UAAU;;iBAGrB,CAAA;AAEF,eAAO,MAAM,YAAY;;iBAGvB,CAAA;AAgCF,eAAO,MAAM,oBAAoB;;;;;iBAgB/B,CAAA;AAuBF,eAAO,MAAM,gBAAgB;;;;;;;;wBAS3B,CAAA;AAEF,eAAO,MAAM,YAAY;;;;;;;;wBAIvB,CAAA;AAEF,eAAO,MAAM,aAAa;;;;;;wBAOxB,CAAA;AAEF,eAAO,MAAM,MAAM;;wBAOjB,CAAA;AAEF,eAAO,MAAM,KAAK;;wBAOhB,CAAA;AAEF,eAAO,MAAM,WAAW;;6BAUtB,CAAA;AAu9DF,eAAO,MAAM,aAAa,GACxB,OAAO,aAAa,EACpB,UAAU,gBAAgB,EAC1B,MAAM,YAAY,EAClB,aAAa,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,6DAkFhC,CAAA"}
1
+ {"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../src/overlay.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,OAAO,EACP,MAAM,EAEN,OAAO,EAGP,MAAM,EAKN,MAAM,IAAI,CAAC,EAGX,eAAe,EAEhB,MAAM,QAAQ,CAAA;AAEf,OAAO,KAAK,OAAO,MAAM,iBAAiB,CAAA;AAC1C,OAAO,EACL,KAAK,aAAa,EAElB,KAAK,aAAa,EAGlB,KAAK,WAAW,EAChB,KAAK,UAAU,EAKhB,MAAM,uBAAuB,CAAA;AAU9B,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;;oFAsDR,CAAC;;;;;;;;;;;;;;;;;AAkQ9D,cAAM,YAAa,SAAQ,iBAE1B;CAAG;;AAEJ,cAAM,iBAAkB,SAAQ,sBAGC;CAAG;AAEpC,eAAO,MAAM,UAAU;;iBAGrB,CAAA;AAEF,eAAO,MAAM,YAAY;;iBAGvB,CAAA;AAgCF,eAAO,MAAM,oBAAoB;;;;;iBAgB/B,CAAA;AAuBF,eAAO,MAAM,gBAAgB;;;;;;;;wBAS3B,CAAA;AAEF,eAAO,MAAM,YAAY;;;;;;;;wBAIvB,CAAA;AAEF,eAAO,MAAM,aAAa;;;;;;wBAOxB,CAAA;AAEF,eAAO,MAAM,MAAM;;wBAOjB,CAAA;AAEF,eAAO,MAAM,KAAK;;wBAOhB,CAAA;AAEF,eAAO,MAAM,WAAW;;6BAUtB,CAAA;AAsgEF,eAAO,MAAM,aAAa,GACxB,OAAO,aAAa,EACpB,UAAU,gBAAgB,EAC1B,MAAM,YAAY,EAClB,aAAa,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,6DAmFhC,CAAA"}
package/dist/overlay.js CHANGED
@@ -118,9 +118,9 @@ const ClickedFollowLatest = m('ClickedFollowLatest');
118
118
  const ClickedScrollToTopPill = m('ClickedScrollToTopPill');
119
119
  const ScrolledMessageList = m('ScrolledMessageList', { scrollTop: S.Number });
120
120
  const CompletedClear = m('CompletedClear');
121
- const LockedScroll = m('LockedScroll');
122
- const UnlockedScroll = m('UnlockedScroll');
123
- const ScrolledToTop = m('ScrolledToTop');
121
+ const CompletedLockScroll = m('CompletedLockScroll');
122
+ const CompletedUnlockScroll = m('CompletedUnlockScroll');
123
+ const CompletedScrollToTop = m('CompletedScrollToTop');
124
124
  const CrossedMobileBreakpoint = m('CrossedMobileBreakpoint', {
125
125
  isMobile: S.Boolean,
126
126
  });
@@ -163,9 +163,9 @@ const Message = S.Union([
163
163
  ScrolledMessageList,
164
164
  CompletedResume,
165
165
  CompletedClear,
166
- LockedScroll,
167
- UnlockedScroll,
168
- ScrolledToTop,
166
+ CompletedLockScroll,
167
+ CompletedUnlockScroll,
168
+ CompletedScrollToTop,
169
169
  CrossedMobileBreakpoint,
170
170
  ReceivedInspectedState,
171
171
  ToggledTreeNode,
@@ -242,12 +242,12 @@ class StoreService extends Context.Service()('foldkit/DevToolsStore') {
242
242
  class ShadowRootService extends Context.Service()('foldkit/DevToolsShadowRoot') {
243
243
  }
244
244
  export const LockScroll = Command.define('LockScroll', {
245
- messages: [LockedScroll],
246
- execute: lockScroll.pipe(Effect.as(LockedScroll())),
245
+ messages: [CompletedLockScroll],
246
+ execute: lockScroll.pipe(Effect.as(CompletedLockScroll())),
247
247
  });
248
248
  export const UnlockScroll = Command.define('UnlockScroll', {
249
- messages: [UnlockedScroll],
250
- execute: unlockScroll.pipe(Effect.as(UnlockedScroll())),
249
+ messages: [CompletedUnlockScroll],
250
+ execute: unlockScroll.pipe(Effect.as(CompletedUnlockScroll())),
251
251
  });
252
252
  const maybeToggleScrollLock = (isEnabled, shouldLock) => __foldkitBrandViewResult((OptionExt.when(isEnabled, shouldLock ? LockScroll() : UnlockScroll())), "@foldkit/devtools/overlay.js#maybeToggleScrollLock");
253
253
  const maybeLockScroll = (isOpen, isMobile) => __foldkitBrandViewResult((OptionExt.when(isOpen && isMobile, LockScroll())), "@foldkit/devtools/overlay.js#maybeLockScroll");
@@ -334,14 +334,14 @@ export const Clear = Command.define('Clear', {
334
334
  }),
335
335
  });
336
336
  export const ScrollToTop = Command.define('ScrollToTop', {
337
- messages: [ScrolledToTop],
337
+ messages: [CompletedScrollToTop],
338
338
  execute: Effect.gen(function* () {
339
339
  const shadow = yield* ShadowRootService;
340
340
  const messageList = shadow.querySelector(MESSAGE_LIST_SELECTOR);
341
341
  if (messageList instanceof HTMLElement) {
342
342
  messageList.scrollTop = 0;
343
343
  }
344
- return __foldkitBrandViewResult((ScrolledToTop()), "@foldkit/devtools/overlay.js#anonymous~23");
344
+ return __foldkitBrandViewResult((CompletedScrollToTop()), "@foldkit/devtools/overlay.js#anonymous~23");
345
345
  }),
346
346
  });
347
347
  const makeUpdate = (store, shadow, mode) => {
@@ -559,7 +559,7 @@ const makeUpdate = (store, shadow, mode) => {
559
559
  [jumpToAndInspect(hostIndex)],
560
560
  ]), "@foldkit/devtools/overlay.js#onSome"),
561
561
  })), "@foldkit/devtools/overlay.js#TickedScrubFrame"),
562
- }), M.tag('CompletedResume', 'CompletedClear', 'CompletedPersistDevToolsState', 'LockedScroll', 'UnlockedScroll', 'ScrolledToTop', () => __foldkitBrandViewResult(([model, []]), "@foldkit/devtools/overlay.js#anonymous~39")), M.exhaustive)), "@foldkit/devtools/overlay.js#anonymous~24")), "@foldkit/devtools/overlay.js#makeUpdate");
562
+ }), M.tag('CompletedResume', 'CompletedClear', 'CompletedPersistDevToolsState', 'CompletedLockScroll', 'CompletedUnlockScroll', 'CompletedScrollToTop', () => __foldkitBrandViewResult(([model, []]), "@foldkit/devtools/overlay.js#anonymous~39")), M.exhaustive)), "@foldkit/devtools/overlay.js#anonymous~24")), "@foldkit/devtools/overlay.js#makeUpdate");
563
563
  };
564
564
  // SUBSCRIPTION
565
565
  const makeOverlaySubscriptions = (store, shadow) => {
@@ -646,12 +646,12 @@ const buildOverlayView = (position, mode, shadow, maybeBanner, h) => {
646
646
  h.StrokeLinecap('round'),
647
647
  h.StrokeLinejoin('round'),
648
648
  h.D(isExpanded ? CHEVRON_DOWN : CHEVRON_RIGHT),
649
- ], []),
649
+ ]),
650
650
  ])), "@foldkit/devtools/overlay.js#arrowView");
651
651
  const tagLabelView = (tag) => __foldkitBrandViewResult((h.span([h.Class('json-tag')], [tag])), "@foldkit/devtools/overlay.js#tagLabelView");
652
652
  const previewView = (preview) => __foldkitBrandViewResult((h.span([h.Class('json-preview')], [preview])), "@foldkit/devtools/overlay.js#previewView");
653
- const diffDotView = h.span([h.Class('diff-dot')], []);
654
- const inlineDiffDotView = h.span([h.Class('diff-dot-inline')], []);
653
+ const diffDotView = h.span([h.Class('diff-dot')]);
654
+ const inlineDiffDotView = h.span([h.Class('diff-dot-inline')]);
655
655
  const ArrowSegment = ts('ArrowSegment', { isExpanded: S.Boolean });
656
656
  const DiffDotSegment = ts('DiffDotSegment');
657
657
  const KeyLabelSegment = ts('KeyLabelSegment', { key: S.String });
@@ -1049,7 +1049,7 @@ const buildOverlayView = (position, mode, shadow, maybeBanner, h) => {
1049
1049
  h.StrokeLinecap('round'),
1050
1050
  h.StrokeLinejoin('round'),
1051
1051
  h.D('M6 18L18 6M6 6l12 12'),
1052
- ], []),
1052
+ ]),
1053
1053
  ])
1054
1054
  : h.div([
1055
1055
  h.Class(clsx('flex flex-col items-center gap-0.5 font-semibold tracking-wider leading-none', model.isPaused ? 'text-dt-bg' : 'text-dt-muted')),
@@ -1070,7 +1070,11 @@ const buildOverlayView = (position, mode, shadow, maybeBanner, h) => {
1070
1070
  h.StrokeWidth('2'),
1071
1071
  h.Stroke('currentColor'),
1072
1072
  ], [
1073
- h.path([h.D(CHECK_ICON), h.StrokeLinecap('round'), h.StrokeLinejoin('round')], []),
1073
+ h.path([
1074
+ h.D(CHECK_ICON),
1075
+ h.StrokeLinecap('round'),
1076
+ h.StrokeLinejoin('round'),
1077
+ ]),
1074
1078
  ]);
1075
1079
  const filterItemLabel = (item) => __foldkitBrandViewResult((String_.isNonEmpty(item) ? submodelLabel(item) : 'All Messages'), "@foldkit/devtools/overlay.js#filterItemLabel");
1076
1080
  const ARROW_UP = 'M4.5 10.5L12 3m0 0l7.5 7.5M12 3v18';
@@ -1083,7 +1087,11 @@ const buildOverlayView = (position, mode, shadow, maybeBanner, h) => {
1083
1087
  h.StrokeWidth('2'),
1084
1088
  h.Stroke('currentColor'),
1085
1089
  ], [
1086
- h.path([h.D(ARROW_UP), h.StrokeLinecap('round'), h.StrokeLinejoin('round')], []),
1090
+ h.path([
1091
+ h.D(ARROW_UP),
1092
+ h.StrokeLinecap('round'),
1093
+ h.StrokeLinejoin('round'),
1094
+ ]),
1087
1095
  ]);
1088
1096
  const scrollToTopPillView = () => __foldkitBrandViewResult((h.button([h.Class('dt-scroll-pill'), h.OnClick(ClickedScrollToTopPill())], [
1089
1097
  arrowUpIconView,
@@ -1120,7 +1128,7 @@ const buildOverlayView = (position, mode, shadow, maybeBanner, h) => {
1120
1128
  h.D(CHEVRON_DOWN),
1121
1129
  h.StrokeLinecap('round'),
1122
1130
  h.StrokeLinejoin('round'),
1123
- ], []),
1131
+ ]),
1124
1132
  ]),
1125
1133
  ]),
1126
1134
  buttonClassName: 'dt-filter-button',
@@ -1137,7 +1145,7 @@ const buildOverlayView = (position, mode, shadow, maybeBanner, h) => {
1137
1145
  isChecked: model.isFlattened,
1138
1146
  onToggle: isFlattened => __foldkitBrandViewResult((ToggledFlatten({ isFlattened })), "@foldkit/devtools/overlay.js#onToggle"),
1139
1147
  toView: attributes => __foldkitBrandViewResult((h.div([h.Class('dt-settings-row')], [
1140
- h.div([...attributes.button, h.Class('dt-switch')], [h.span([h.Class('dt-switch-thumb')], [])]),
1148
+ h.div([...attributes.button, h.Class('dt-switch')], [h.span([h.Class('dt-switch-thumb')])]),
1141
1149
  h.div([h.Class('dt-settings-row-text')], [
1142
1150
  h.label([...attributes.label, h.Class('dt-settings-row-label')], ['Flatten to leaf Message']),
1143
1151
  h.span([
@@ -1186,8 +1194,8 @@ const buildOverlayView = (position, mode, shadow, maybeBanner, h) => {
1186
1194
  h.OnClick(ClickedRow({ index: INIT_INDEX })),
1187
1195
  ], [
1188
1196
  ...OptionExt.when(mode === 'TimeTravel', h.span([h.Class('pause-column')], isPausedHere ? [pauseIconView] : [])).pipe(Option.toArray),
1189
- h.span([h.Class('dot-column')], []),
1190
- h.span([h.Class(indexClass)], []),
1197
+ h.span([h.Class('dot-column')]),
1198
+ h.span([h.Class(indexClass)]),
1191
1199
  h.span([h.Class('text-base text-dt-muted font-mono')], ['init']),
1192
1200
  ])), "@foldkit/devtools/overlay.js#initRowView");
1193
1201
  const pauseIconView = h.svg([
@@ -1203,7 +1211,7 @@ const buildOverlayView = (position, mode, shadow, maybeBanner, h) => {
1203
1211
  h.StrokeLinecap('round'),
1204
1212
  h.StrokeLinejoin('round'),
1205
1213
  h.D('M5.75 3v18M18.25 3v18'),
1206
- ], []),
1214
+ ]),
1207
1215
  ]);
1208
1216
  const messageRowView = (tag, absoluteIndex, isSelected, isPausedHere, timeDelta, isModelChanged) => __foldkitBrandViewResult((h.keyed('li')(String(absoluteIndex), [
1209
1217
  h.Class(clsx(ROW_BASE, { selected: isSelected })),
@@ -1301,8 +1309,11 @@ const buildOverlayView = (position, mode, shadow, maybeBanner, h) => {
1301
1309
  h.div([
1302
1310
  ...attributes.filledTrack,
1303
1311
  h.Class('dt-scrubber-fill'),
1304
- ], []),
1305
- h.div([...attributes.thumb, h.Class('dt-scrubber-thumb')], []),
1312
+ ]),
1313
+ h.div([
1314
+ ...attributes.thumb,
1315
+ h.Class('dt-scrubber-thumb'),
1316
+ ]),
1306
1317
  ]),
1307
1318
  ]),
1308
1319
  h.span([
@@ -1326,8 +1337,16 @@ const buildOverlayView = (position, mode, shadow, maybeBanner, h) => {
1326
1337
  h.StrokeWidth('1.5'),
1327
1338
  h.Stroke('currentColor'),
1328
1339
  ], [
1329
- h.path([h.D(GEAR_OUTER), h.StrokeLinecap('round'), h.StrokeLinejoin('round')], []),
1330
- h.path([h.D(GEAR_INNER), h.StrokeLinecap('round'), h.StrokeLinejoin('round')], []),
1340
+ h.path([
1341
+ h.D(GEAR_OUTER),
1342
+ h.StrokeLinecap('round'),
1343
+ h.StrokeLinejoin('round'),
1344
+ ]),
1345
+ h.path([
1346
+ h.D(GEAR_INNER),
1347
+ h.StrokeLinecap('round'),
1348
+ h.StrokeLinejoin('round'),
1349
+ ]),
1331
1350
  ]);
1332
1351
  const closeSettingsIconView = h.svg([
1333
1352
  h.AriaHidden(true),
@@ -1338,7 +1357,11 @@ const buildOverlayView = (position, mode, shadow, maybeBanner, h) => {
1338
1357
  h.StrokeWidth('2'),
1339
1358
  h.Stroke('currentColor'),
1340
1359
  ], [
1341
- h.path([h.D(X_MARK), h.StrokeLinecap('round'), h.StrokeLinejoin('round')], []),
1360
+ h.path([
1361
+ h.D(X_MARK),
1362
+ h.StrokeLinecap('round'),
1363
+ h.StrokeLinejoin('round'),
1364
+ ]),
1342
1365
  ]);
1343
1366
  const settingsToggleView = (screen) => {
1344
1367
  const isSettingsOpen = screen === 'Settings';
@@ -1381,7 +1404,7 @@ const buildOverlayView = (position, mode, shadow, maybeBanner, h) => {
1381
1404
  contentView(model),
1382
1405
  footerView(model),
1383
1406
  ])), "@foldkit/devtools/overlay.js#panelView");
1384
- const interactionBlocker = () => __foldkitBrandViewResult((h.div([h.Class('dt-interaction-blocker')], [])), "@foldkit/devtools/overlay.js#interactionBlocker");
1407
+ const interactionBlocker = () => __foldkitBrandViewResult((h.div([h.Class('dt-interaction-blocker')])), "@foldkit/devtools/overlay.js#interactionBlocker");
1385
1408
  return __foldkitBrandViewResult(((model) => __foldkitBrandViewResult((h.div([], [
1386
1409
  ...OptionExt.when(model.isPaused && mode === 'TimeTravel', interactionBlocker()).pipe(Option.toArray),
1387
1410
  ...OptionExt.when(model.isOpen, panelView(model)).pipe(Option.toArray),
@@ -1389,11 +1412,55 @@ const buildOverlayView = (position, mode, shadow, maybeBanner, h) => {
1389
1412
  ])), "@foldkit/devtools/overlay.js#anonymous~91")), "@foldkit/devtools/overlay.js#buildOverlayView");
1390
1413
  };
1391
1414
  // CREATE
1415
+ const VIEW_TRANSITION_NAME = 'foldkit-devtools';
1416
+ const VIEW_TRANSITION_STYLE_ID = 'foldkit-devtools-view-transition';
1417
+ /**
1418
+ * Holds the overlay still through an application's View Transitions.
1419
+ *
1420
+ * The host's `view-transition-name` lifts the overlay out of the page's root
1421
+ * snapshot, which is what stops it cross-fading with the page. The browser then
1422
+ * gives it its own pair of snapshots and cross-fades those against each other
1423
+ * instead. The overlay is identical on both sides of any application render, so
1424
+ * rather than rely on that cross-fade being lossless, the outgoing snapshot is
1425
+ * hidden and the incoming one held opaque.
1426
+ *
1427
+ * Only the two snapshots are pinned. The host spans the viewport, so its old
1428
+ * and new geometry are identical and the group's animation is already a no-op;
1429
+ * there is nothing to gain by overriding it.
1430
+ *
1431
+ * These pseudo-elements live on the top-level document, which the overlay's own
1432
+ * shadow styles cannot reach, so the rule goes in `document.head`.
1433
+ */
1434
+ const installViewTransitionStyle = () => {
1435
+ if (document.getElementById(VIEW_TRANSITION_STYLE_ID) !== null) {
1436
+ return;
1437
+ }
1438
+ const style = document.createElement('style');
1439
+ style.id = VIEW_TRANSITION_STYLE_ID;
1440
+ // NOTE: the UA composites these snapshots with `plus-lighter`, which is
1441
+ // right for a cross-fade and wrong for a snapshot held opaque: it adds to
1442
+ // the backdrop and washes the overlay out.
1443
+ style.textContent = `
1444
+ ::view-transition-old(${VIEW_TRANSITION_NAME}) {
1445
+ animation: none;
1446
+ opacity: 0;
1447
+ mix-blend-mode: normal;
1448
+ }
1449
+
1450
+ ::view-transition-new(${VIEW_TRANSITION_NAME}) {
1451
+ animation: none;
1452
+ opacity: 1;
1453
+ mix-blend-mode: normal;
1454
+ }
1455
+ `;
1456
+ document.head.appendChild(style);
1457
+ };
1392
1458
  const createShadowContainer = () => {
1393
1459
  const existingHost = document.getElementById(DEVTOOLS_HOST_ID);
1394
1460
  if (existingHost) {
1395
1461
  existingHost.remove();
1396
1462
  }
1463
+ installViewTransitionStyle();
1397
1464
  const host = document.createElement('div');
1398
1465
  host.id = DEVTOOLS_HOST_ID;
1399
1466
  host.addEventListener('pointerdown', event => {
@@ -1404,6 +1471,15 @@ const createShadowContainer = () => {
1404
1471
  event.preventDefault();
1405
1472
  }
1406
1473
  }, { capture: true });
1474
+ // NOTE: the name is set here, not on `:host` alongside every other host
1475
+ // property. A `view-transition-name` reaching the host through a shadow
1476
+ // `:host` rule computes (`getComputedStyle` reports it) but Chromium does
1477
+ // not then capture the element as its own snapshot, so the overlay stays in
1478
+ // the page's root snapshot and cross-fades with it. Authored from the light
1479
+ // DOM it captures. Observed in Chromium 149 and not checked elsewhere;
1480
+ // moving this into the stylesheet reintroduces the fade with no other
1481
+ // symptom.
1482
+ host.style.viewTransitionName = VIEW_TRANSITION_NAME;
1407
1483
  document.body.appendChild(host);
1408
1484
  const shadow = host.attachShadow({ mode: 'open' });
1409
1485
  const styleElement = document.createElement('style');
@@ -1416,6 +1492,7 @@ const createShadowContainer = () => {
1416
1492
  export const createOverlay = (store, position, mode, maybeBanner) => __foldkitBrandViewResult((Effect.gen(function* () {
1417
1493
  const { container, shadow } = yield* Effect.acquireRelease(Effect.sync(() => __foldkitBrandViewResult((createShadowContainer()), "@foldkit/devtools/overlay.js#anonymous~94")), createdShadowContainer => __foldkitBrandViewResult((Effect.sync(() => {
1418
1494
  createdShadowContainer.shadow.host.remove();
1495
+ document.getElementById(VIEW_TRANSITION_STYLE_ID)?.remove();
1419
1496
  })), "@foldkit/devtools/overlay.js#anonymous~95"));
1420
1497
  container.id = '__foldkit_devtools_overlay__';
1421
1498
  const flags = Effect.gen(function* () {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@foldkit/devtools",
3
- "version": "0.136.0",
3
+ "version": "0.138.0",
4
4
  "description": "In-browser DevTools overlay for Foldkit applications",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -31,9 +31,9 @@
31
31
  "rimraf": "^6.1.3",
32
32
  "typescript": "^6.0.3",
33
33
  "vitest": "^4.1.9",
34
- "@foldkit/ui": "0.136.0",
35
- "foldkit": "0.136.0",
36
- "@foldkit/vite-plugin": "0.11.3"
34
+ "@foldkit/ui": "0.138.0",
35
+ "@foldkit/vite-plugin": "0.11.3",
36
+ "foldkit": "0.138.0"
37
37
  },
38
38
  "keywords": [
39
39
  "foldkit",