@docmentis/udoc-viewer 0.2.10 → 0.2.11

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.
Files changed (62) hide show
  1. package/dist/package.json +1 -1
  2. package/dist/src/UDocViewer.d.ts.map +1 -1
  3. package/dist/src/UDocViewer.js +4 -0
  4. package/dist/src/UDocViewer.js.map +1 -1
  5. package/dist/src/performance/PerformanceCounter.d.ts +1 -1
  6. package/dist/src/performance/PerformanceCounter.d.ts.map +1 -1
  7. package/dist/src/performance/PerformanceCounter.js.map +1 -1
  8. package/dist/src/ui/viewer/actions.d.ts +10 -0
  9. package/dist/src/ui/viewer/actions.d.ts.map +1 -1
  10. package/dist/src/ui/viewer/components/Spread.d.ts +2 -0
  11. package/dist/src/ui/viewer/components/Spread.d.ts.map +1 -1
  12. package/dist/src/ui/viewer/components/Spread.js +57 -3
  13. package/dist/src/ui/viewer/components/Spread.js.map +1 -1
  14. package/dist/src/ui/viewer/components/Viewport.d.ts.map +1 -1
  15. package/dist/src/ui/viewer/components/Viewport.js +7 -3
  16. package/dist/src/ui/viewer/components/Viewport.js.map +1 -1
  17. package/dist/src/ui/viewer/effects.d.ts.map +1 -1
  18. package/dist/src/ui/viewer/effects.js +51 -3
  19. package/dist/src/ui/viewer/effects.js.map +1 -1
  20. package/dist/src/ui/viewer/reducer.d.ts.map +1 -1
  21. package/dist/src/ui/viewer/reducer.js +33 -1
  22. package/dist/src/ui/viewer/reducer.js.map +1 -1
  23. package/dist/src/ui/viewer/shell.d.ts +4 -0
  24. package/dist/src/ui/viewer/shell.d.ts.map +1 -1
  25. package/dist/src/ui/viewer/shell.js.map +1 -1
  26. package/dist/src/ui/viewer/state.d.ts +5 -0
  27. package/dist/src/ui/viewer/state.d.ts.map +1 -1
  28. package/dist/src/ui/viewer/state.js +2 -0
  29. package/dist/src/ui/viewer/state.js.map +1 -1
  30. package/dist/src/ui/viewer/styles-inline.d.ts +1 -1
  31. package/dist/src/ui/viewer/styles-inline.d.ts.map +1 -1
  32. package/dist/src/ui/viewer/styles-inline.js +25 -1
  33. package/dist/src/ui/viewer/styles-inline.js.map +1 -1
  34. package/dist/src/ui/viewer/text/index.d.ts +7 -0
  35. package/dist/src/ui/viewer/text/index.d.ts.map +1 -0
  36. package/dist/src/ui/viewer/text/index.js +3 -0
  37. package/dist/src/ui/viewer/text/index.js.map +1 -0
  38. package/dist/src/ui/viewer/text/render.d.ts +19 -0
  39. package/dist/src/ui/viewer/text/render.d.ts.map +1 -0
  40. package/dist/src/ui/viewer/text/render.js +135 -0
  41. package/dist/src/ui/viewer/text/render.js.map +1 -0
  42. package/dist/src/ui/viewer/text/selection.d.ts +12 -0
  43. package/dist/src/ui/viewer/text/selection.d.ts.map +1 -0
  44. package/dist/src/ui/viewer/text/selection.js +70 -0
  45. package/dist/src/ui/viewer/text/selection.js.map +1 -0
  46. package/dist/src/ui/viewer/text/types.d.ts +37 -0
  47. package/dist/src/ui/viewer/text/types.d.ts.map +1 -0
  48. package/dist/src/ui/viewer/text/types.js +7 -0
  49. package/dist/src/ui/viewer/text/types.js.map +1 -0
  50. package/dist/src/wasm/udoc.d.ts +11 -0
  51. package/dist/src/wasm/udoc.js +33 -0
  52. package/dist/src/wasm/udoc_bg.wasm +0 -0
  53. package/dist/src/wasm/udoc_bg.wasm.d.ts +1 -0
  54. package/dist/src/worker/WorkerClient.d.ts +4 -0
  55. package/dist/src/worker/WorkerClient.d.ts.map +1 -1
  56. package/dist/src/worker/WorkerClient.js +18 -0
  57. package/dist/src/worker/WorkerClient.js.map +1 -1
  58. package/dist/src/worker/worker.d.ts +12 -0
  59. package/dist/src/worker/worker.d.ts.map +1 -1
  60. package/dist/src/worker/worker.js +6 -0
  61. package/dist/src/worker/worker.js.map +1 -1
  62. package/package.json +1 -1
@@ -1,2 +1,2 @@
1
- export declare const inlineStyles = ".udoc-viewer-root {\n display: flex;\n flex-direction: column;\n height: 100%;\n container-type: inline-size;\n container-name: udoc-viewer;\n}\n\n.udoc-viewer-root .udoc-toolbar-slot {\n flex: 0 0 auto;\n}\n\n.udoc-viewer-root .udoc-body-slot {\n flex: 1 1 auto;\n display: flex;\n overflow: hidden;\n}\n\n.udoc-viewer-root .udoc-left-panel-slot {\n flex: 0 0 auto;\n}\n\n.udoc-viewer-root .udoc-right-panel-slot {\n flex: 0 0 auto;\n}\n\n.udoc-viewer-root .udoc-viewport-slot {\n position: relative;\n flex: 1 1 auto;\n overflow: hidden;\n}\n\n.udoc-viewer-root .udoc-viewport {\n position: relative;\n width: 100%;\n height: 100%;\n background: #e0e0e0;\n}\n\n.udoc-viewer-root .udoc-viewport__scroll {\n width: 100%;\n height: 100%;\n overflow: auto;\n scrollbar-gutter: stable;\n}\n\n.udoc-viewer-root .udoc-viewport__container {\n position: relative;\n min-height: 100%;\n box-sizing: border-box;\n /* height set dynamically for virtual scrolling */\n}\n\n.udoc-viewer-root .udoc-viewport__watermark {\n position: absolute;\n right: 18px;\n bottom: 4px;\n padding: 2px 6px;\n font-size: 12px;\n font-weight: 500;\n color: rgba(0, 0, 0, 0.3);\n text-decoration: none;\n text-shadow: 0 1px 2px rgba(255, 255, 255, 0.5);\n z-index: 10;\n transition: color 0.15s ease;\n}\n\n.udoc-viewer-root .udoc-viewport__watermark:hover {\n color: rgba(0, 0, 0, 0.6);\n}\n\n/* Spread */\n.udoc-viewer-root .udoc-spread {\n display: flex;\n flex-direction: row;\n justify-content: flex-start;\n flex-shrink: 0;\n}\n\n.udoc-viewer-root .udoc-spread--hidden {\n display: none;\n}\n\n/* Page slot within spread */\n.udoc-viewer-root .udoc-spread__slot {\n display: flex;\n align-items: center;\n justify-content: center;\n background: white;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n}\n\n.udoc-viewer-root .udoc-viewport--seamless .udoc-spread__slot {\n box-shadow: none;\n}\n\n.udoc-viewer-root .udoc-spread__slot--empty {\n background: transparent;\n box-shadow: none;\n}\n\n.udoc-viewer-root .udoc-spread__canvas {\n display: block;\n}\n\n/* Floating Toolbar */\n.udoc-viewer-root .udoc-floating-toolbar {\n position: absolute;\n bottom: 24px;\n left: 50%;\n transform: translateX(-50%);\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 6px 10px;\n background: #fff;\n border-radius: 8px;\n box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);\n z-index: 100;\n}\n\n.udoc-viewer-root .udoc-floating-toolbar__section {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.udoc-viewer-root .udoc-floating-toolbar__divider {\n width: 1px;\n height: 20px;\n background: rgba(0, 0, 0, 0.15);\n margin: 0 4px;\n}\n\n.udoc-viewer-root .udoc-floating-toolbar__btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n padding: 0;\n border: none;\n border-radius: 4px;\n background: transparent;\n color: rgba(0, 0, 0, 0.7);\n cursor: pointer;\n}\n\n.udoc-viewer-root .udoc-floating-toolbar__btn:hover {\n background: rgba(0, 0, 0, 0.08);\n}\n\n.udoc-viewer-root .udoc-floating-toolbar__btn:active {\n background: rgba(0, 0, 0, 0.15);\n}\n\n.udoc-viewer-root .udoc-floating-toolbar__btn:disabled {\n color: rgba(0, 0, 0, 0.25);\n cursor: default;\n}\n\n.udoc-viewer-root .udoc-floating-toolbar__btn:disabled:hover {\n background: transparent;\n}\n\n.udoc-viewer-root .udoc-floating-toolbar__btn svg {\n width: 18px;\n height: 18px;\n}\n\n.udoc-viewer-root .udoc-floating-toolbar__page-info {\n display: flex;\n align-items: center;\n color: rgba(0, 0, 0, 0.8);\n font-size: 13px;\n}\n\n.udoc-viewer-root .udoc-floating-toolbar__page-input {\n width: 36px;\n padding: 2px 4px;\n border: 1px solid rgba(0, 0, 0, 0.15);\n border-radius: 4px;\n background: transparent;\n color: rgba(0, 0, 0, 0.8);\n font-size: 13px;\n text-align: center;\n}\n\n.udoc-viewer-root .udoc-floating-toolbar__page-input:focus {\n outline: none;\n border-color: rgba(0, 0, 0, 0.3);\n background: white;\n}\n\n.udoc-viewer-root .udoc-floating-toolbar__page-total {\n white-space: nowrap;\n}\n\n.udoc-viewer-root .udoc-floating-toolbar__zoom-level {\n min-width: 44px;\n color: rgba(0, 0, 0, 0.8);\n font-size: 13px;\n text-align: center;\n}\n\n.udoc-viewer-root .udoc-floating-toolbar__btn--active {\n background: rgba(0, 0, 0, 0.12);\n}\n\n/* Zoom Dropdown */\n.udoc-viewer-root .udoc-zoom-dropdown {\n position: relative;\n height: 28px;\n display: flex;\n align-items: center;\n}\n\n.udoc-viewer-root .udoc-zoom-dropdown__toggle {\n display: flex;\n align-items: center;\n gap: 0;\n height: 100%;\n border: 1px solid rgba(0, 0, 0, 0.15);\n border-radius: 4px;\n background: transparent;\n}\n\n.udoc-viewer-root .udoc-zoom-dropdown__toggle:focus-within {\n border-color: rgba(0, 0, 0, 0.3);\n background: white;\n}\n\n.udoc-viewer-root .udoc-zoom-dropdown__input {\n width: 44px;\n padding: 2px 4px;\n border: none;\n border-radius: 4px 0 0 4px;\n background: transparent;\n color: rgba(0, 0, 0, 0.8);\n font-size: 13px;\n text-align: center;\n}\n\n.udoc-viewer-root .udoc-zoom-dropdown__input:focus {\n outline: none;\n}\n\n.udoc-viewer-root .udoc-zoom-dropdown__chevron {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 2px 2px;\n border: none;\n border-left: 1px solid rgba(0, 0, 0, 0.1);\n border-radius: 0 4px 4px 0;\n background: transparent;\n color: rgba(0, 0, 0, 0.5);\n cursor: pointer;\n}\n\n.udoc-viewer-root .udoc-zoom-dropdown__chevron:hover {\n background: rgba(0, 0, 0, 0.08);\n color: rgba(0, 0, 0, 0.7);\n}\n\n.udoc-viewer-root .udoc-zoom-dropdown__chevron--active {\n background: rgba(0, 0, 0, 0.12);\n}\n\n.udoc-viewer-root .udoc-zoom-dropdown__chevron svg {\n width: 14px;\n height: 14px;\n}\n\n.udoc-viewer-root .udoc-zoom-dropdown__menu {\n position: absolute;\n bottom: calc(100% + 8px);\n left: 50%;\n transform: translateX(-50%);\n padding: 6px;\n background: #fff;\n border-radius: 8px;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);\n min-width: 100px;\n}\n\n.udoc-viewer-root .udoc-zoom-dropdown__section {\n display: flex;\n flex-direction: column;\n}\n\n.udoc-viewer-root .udoc-zoom-dropdown__divider {\n height: 1px;\n background: rgba(0, 0, 0, 0.1);\n margin: 6px 0;\n}\n\n.udoc-viewer-root .udoc-zoom-dropdown__item {\n display: block;\n width: 100%;\n padding: 6px 10px;\n border: none;\n border-radius: 4px;\n background: transparent;\n color: rgba(0, 0, 0, 0.8);\n font-size: 13px;\n text-align: left;\n cursor: pointer;\n white-space: nowrap;\n}\n\n.udoc-viewer-root .udoc-zoom-dropdown__item:hover {\n background: rgba(0, 0, 0, 0.08);\n}\n\n.udoc-viewer-root .udoc-zoom-dropdown__item--active {\n background: rgba(0, 102, 204, 0.15);\n color: #0066cc;\n}\n\n.udoc-viewer-root .udoc-zoom-dropdown__item--active:hover {\n background: rgba(0, 102, 204, 0.2);\n}\n\n/* View Mode Menu */\n.udoc-viewer-root .udoc-view-mode-menu {\n position: relative;\n height: 28px;\n display: flex;\n align-items: center;\n}\n\n.udoc-viewer-root .udoc-view-mode-menu__dropdown {\n position: absolute;\n bottom: calc(100% + 8px);\n left: 0;\n padding: 8px;\n background: #fff;\n border-radius: 8px;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);\n min-width: 160px;\n}\n\n.udoc-viewer-root .udoc-view-mode-menu__section {\n margin-bottom: 8px;\n}\n\n.udoc-viewer-root .udoc-view-mode-menu__section:last-child {\n margin-bottom: 0;\n}\n\n.udoc-viewer-root .udoc-view-mode-menu__title {\n font-size: 10px;\n font-weight: 600;\n text-transform: uppercase;\n color: rgba(0, 0, 0, 0.5);\n margin-bottom: 4px;\n padding: 0 4px;\n}\n\n.udoc-viewer-root .udoc-view-mode-menu__options {\n display: flex;\n gap: 2px;\n}\n\n.udoc-viewer-root .udoc-view-mode-menu__option {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n padding: 0;\n border: none;\n border-radius: 4px;\n background: transparent;\n color: rgba(0, 0, 0, 0.6);\n cursor: pointer;\n}\n\n.udoc-viewer-root .udoc-view-mode-menu__option:hover {\n background: rgba(0, 0, 0, 0.08);\n}\n\n.udoc-viewer-root .udoc-view-mode-menu__option--active {\n background: rgba(0, 102, 204, 0.15);\n color: #0066cc;\n}\n\n.udoc-viewer-root .udoc-view-mode-menu__option--active:hover {\n background: rgba(0, 102, 204, 0.2);\n}\n\n.udoc-viewer-root .udoc-view-mode-menu__option--disabled {\n color: rgba(0, 0, 0, 0.25);\n cursor: default;\n}\n\n.udoc-viewer-root .udoc-view-mode-menu__option--disabled:hover {\n background: transparent;\n}\n\n.udoc-viewer-root .udoc-view-mode-menu__option-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.udoc-viewer-root .udoc-view-mode-menu__option-icon svg {\n width: 20px;\n height: 20px;\n}\n\n/* Left Panel */\n.udoc-viewer-root .udoc-left-panel {\n position: relative;\n display: flex;\n width: 240px;\n height: 100%;\n background: #f5f5f5;\n border-right: 1px solid #ddd;\n transition: width 0.2s ease, opacity 0.2s ease;\n}\n\n.udoc-viewer-root .udoc-left-panel--closed {\n width: 0;\n overflow: hidden;\n border-right: none;\n}\n\n.udoc-viewer-root .udoc-left-panel__tabs {\n display: flex;\n flex-direction: column;\n width: 40px;\n background: #e8e8e8;\n border-right: 1px solid #ddd;\n}\n\n.udoc-viewer-root .udoc-left-panel__tab {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n padding: 0;\n border: none;\n background: transparent;\n color: #666;\n cursor: pointer;\n}\n\n.udoc-viewer-root .udoc-left-panel__tab:hover {\n background: rgba(0, 0, 0, 0.08);\n}\n\n.udoc-viewer-root .udoc-left-panel__tab--active {\n background: #f5f5f5;\n color: #333;\n border-right: 2px solid #0066cc;\n}\n\n.udoc-viewer-root .udoc-left-panel__tab svg {\n width: 20px;\n height: 20px;\n}\n\n.udoc-viewer-root .udoc-left-panel__content {\n flex: 1;\n overflow: hidden;\n}\n\n.udoc-viewer-root .udoc-left-panel__resize-handle {\n position: absolute;\n right: 0;\n top: 0;\n width: 4px;\n height: 100%;\n cursor: col-resize;\n background: transparent;\n z-index: 10;\n}\n\n.udoc-viewer-root .udoc-left-panel__resize-handle:hover,\n.udoc-viewer-root .udoc-left-panel--resizing .udoc-left-panel__resize-handle {\n background: rgba(0, 102, 204, 0.3);\n}\n\n.udoc-viewer-root .udoc-left-panel--resizing {\n transition: none;\n}\n\n/* Thumbnail Panel */\n.udoc-viewer-root .udoc-thumbnail-panel {\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 12px;\n height: 100%;\n overflow-y: auto;\n overflow-x: hidden;\n}\n\n.udoc-viewer-root .udoc-thumbnail-item {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n padding: 8px;\n border-radius: 4px;\n cursor: pointer;\n transition: background 0.15s ease;\n flex-shrink: 0;\n width: 100%;\n box-sizing: border-box;\n}\n\n.udoc-viewer-root .udoc-thumbnail-item:hover {\n background: rgba(0, 0, 0, 0.05);\n}\n\n.udoc-viewer-root .udoc-thumbnail-item--active {\n background: rgba(0, 102, 204, 0.1);\n outline: 2px solid #0066cc;\n outline-offset: -2px;\n}\n\n.udoc-viewer-root .udoc-thumbnail-item__canvas {\n display: block;\n max-width: calc(100% - 16px);\n background: white;\n box-shadow: 0 1px 4px rgba(0, 0, 0, 0.15);\n}\n\n.udoc-viewer-root .udoc-thumbnail-item__label {\n font-size: 11px;\n color: #666;\n text-align: center;\n}\n\n.udoc-viewer-root .udoc-thumbnail-item--active .udoc-thumbnail-item__label {\n color: #0066cc;\n font-weight: 500;\n}\n\n/* Outline Panel */\n.udoc-viewer-root .udoc-outline-panel {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow-y: auto;\n overflow-x: hidden;\n padding: 8px 0;\n}\n\n.udoc-viewer-root .udoc-outline-panel__loading,\n.udoc-viewer-root .udoc-outline-panel__empty {\n padding: 16px;\n color: #888;\n font-size: 13px;\n text-align: center;\n}\n\n.udoc-viewer-root .udoc-outline-item {\n display: flex;\n flex-direction: column;\n}\n\n.udoc-viewer-root .udoc-outline-item__header {\n display: flex;\n align-items: center;\n padding: 6px 12px 6px 8px;\n gap: 4px;\n min-height: 28px;\n}\n\n.udoc-viewer-root .udoc-outline-item__header--clickable {\n cursor: pointer;\n}\n\n.udoc-viewer-root .udoc-outline-item__header--clickable:hover {\n background: rgba(0, 0, 0, 0.05);\n}\n\n.udoc-viewer-root .udoc-outline-item__header--active {\n background: rgba(0, 102, 204, 0.1);\n}\n\n.udoc-viewer-root .udoc-outline-item__header--active .udoc-outline-item__title {\n color: #0066cc;\n font-weight: 500;\n}\n\n.udoc-viewer-root .udoc-outline-item__toggle {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n padding: 0;\n border: none;\n background: transparent;\n color: #666;\n cursor: pointer;\n flex-shrink: 0;\n transition: transform 0.15s ease;\n}\n\n.udoc-viewer-root .udoc-outline-item__toggle:hover {\n color: #333;\n}\n\n.udoc-viewer-root .udoc-outline-item__toggle--expanded {\n transform: rotate(90deg);\n}\n\n.udoc-viewer-root .udoc-outline-item__spacer {\n width: 16px;\n flex-shrink: 0;\n}\n\n.udoc-viewer-root .udoc-outline-item__title {\n font-size: 13px;\n color: #333;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n flex: 1;\n}\n\n/* .udoc-outline-item__children: Indentation is handled via padding-left on header */\n\n.udoc-viewer-root .udoc-toolbar {\n display: flex;\n align-items: center;\n height: 40px;\n padding: 0 8px;\n background: #f5f5f5;\n border-bottom: 1px solid #ddd;\n}\n\n.udoc-viewer-root .udoc-toolbar__left,\n.udoc-viewer-root .udoc-toolbar__right {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.udoc-viewer-root .udoc-toolbar__spacer {\n flex: 1;\n}\n\n.udoc-viewer-root .udoc-toolbar__btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n padding: 0;\n border: none;\n border-radius: 4px;\n background: transparent;\n color: #555;\n cursor: pointer;\n}\n\n.udoc-viewer-root .udoc-toolbar__btn:hover {\n background: rgba(0, 0, 0, 0.08);\n}\n\n.udoc-viewer-root .udoc-toolbar__btn:active {\n background: rgba(0, 0, 0, 0.12);\n}\n\n.udoc-viewer-root .udoc-toolbar__btn svg {\n width: 20px;\n height: 20px;\n}\n\n/* Right Panel */\n.udoc-viewer-root .udoc-right-panel {\n position: relative;\n display: flex;\n flex-direction: column;\n width: 300px;\n height: 100%;\n background: #f5f5f5;\n border-left: 1px solid #ddd;\n transition: width 0.2s ease, opacity 0.2s ease;\n}\n\n.udoc-viewer-root .udoc-right-panel--closed {\n width: 0;\n overflow: hidden;\n border-left: none;\n}\n\n.udoc-viewer-root .udoc-right-panel__resize-handle {\n position: absolute;\n left: 0;\n top: 0;\n width: 4px;\n height: 100%;\n cursor: col-resize;\n background: transparent;\n z-index: 10;\n}\n\n.udoc-viewer-root .udoc-right-panel__resize-handle:hover,\n.udoc-viewer-root .udoc-right-panel--resizing .udoc-right-panel__resize-handle {\n background: rgba(0, 102, 204, 0.3);\n}\n\n.udoc-viewer-root .udoc-right-panel--resizing {\n transition: none;\n}\n\n.udoc-viewer-root .udoc-right-panel__content {\n flex: 1;\n overflow: auto;\n}\n\n/* Annotation Layer */\n.udoc-viewer-root .udoc-spread__annotation-layer {\n position: absolute;\n pointer-events: none;\n z-index: 1;\n}\n\n/* Base annotation */\n.udoc-viewer-root .udoc-annotation {\n position: absolute;\n box-sizing: border-box;\n}\n\n/* Link annotation */\n.udoc-viewer-root .udoc-annotation--link {\n pointer-events: auto;\n cursor: pointer;\n transition: background-color 0.15s ease;\n}\n\n.udoc-viewer-root .udoc-annotation--link:hover {\n background-color: rgba(0, 102, 204, 0.15);\n}\n\n/* Highlight annotation */\n.udoc-viewer-root .udoc-annotation--highlight {\n pointer-events: none;\n}\n\n.udoc-viewer-root .udoc-annotation__quad {\n mix-blend-mode: multiply;\n}\n\n/* Underline annotation */\n.udoc-viewer-root .udoc-annotation--underline {\n pointer-events: none;\n}\n\n/* StrikeOut annotation */\n.udoc-viewer-root .udoc-annotation--strikeout {\n pointer-events: none;\n}\n\n/* Squiggly annotation */\n.udoc-viewer-root .udoc-annotation--squiggly {\n pointer-events: none;\n}\n\n/* Text (sticky note) annotation */\n.udoc-viewer-root .udoc-annotation--text {\n pointer-events: auto;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: filter 0.15s ease;\n}\n\n.udoc-viewer-root .udoc-annotation--text:hover {\n filter: brightness(1.1) drop-shadow(0 1px 2px rgba(0, 0, 0, 0.3));\n}\n\n.udoc-viewer-root .udoc-annotation--text svg {\n width: 100%;\n height: 100%;\n}\n\n/* Annotation popup */\n.udoc-viewer-root .udoc-annotation-popup {\n position: absolute;\n z-index: 100;\n min-width: 200px;\n max-width: 300px;\n background: #ffffc0;\n border: 1px solid #d4d4a0;\n border-radius: 4px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);\n font-size: 12px;\n color: #333;\n pointer-events: auto;\n}\n\n.udoc-viewer-root .udoc-annotation-popup__header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 6px 8px;\n background: #f0f0c0;\n border-bottom: 1px solid #d4d4a0;\n border-radius: 4px 4px 0 0;\n}\n\n.udoc-viewer-root .udoc-annotation-popup__author {\n font-weight: 600;\n color: #555;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.udoc-viewer-root .udoc-annotation-popup__close {\n width: 16px;\n height: 16px;\n border: none;\n background: transparent;\n cursor: pointer;\n padding: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0.6;\n flex-shrink: 0;\n margin-left: 8px;\n}\n\n.udoc-viewer-root .udoc-annotation-popup__close:hover {\n opacity: 1;\n}\n\n.udoc-viewer-root .udoc-annotation-popup__close svg {\n width: 12px;\n height: 12px;\n}\n\n.udoc-viewer-root .udoc-annotation-popup__content {\n padding: 8px;\n white-space: pre-wrap;\n word-wrap: break-word;\n max-height: 200px;\n overflow-y: auto;\n}\n\n/* FreeText annotation */\n.udoc-viewer-root .udoc-annotation--freetext {\n pointer-events: auto;\n overflow: hidden;\n font-size: 12px;\n padding: 2px;\n}\n\n/* Stamp annotation */\n.udoc-viewer-root .udoc-annotation--stamp {\n pointer-events: none;\n}\n\n/* Caret annotation - rendered via SVG, minimal styling needed */\n.udoc-viewer-root .udoc-annotation--caret {\n pointer-events: none;\n}\n\n/* Shape annotations - rendered via SVG overlay */\n.udoc-viewer-root .udoc-annotation--line,\n.udoc-viewer-root .udoc-annotation--square,\n.udoc-viewer-root .udoc-annotation--circle,\n.udoc-viewer-root .udoc-annotation--polygon,\n.udoc-viewer-root .udoc-annotation--polyLine,\n.udoc-viewer-root .udoc-annotation--ink {\n pointer-events: none;\n}\n\n/* Redact annotation */\n.udoc-viewer-root .udoc-annotation--redact {\n pointer-events: none;\n}\n\n/* Annotation Panel */\n.udoc-viewer-root .udoc-annotation-panel {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.udoc-viewer-root .udoc-annotation-panel__placeholder {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n padding: 32px 16px;\n text-align: center;\n color: #888;\n}\n\n.udoc-viewer-root .udoc-annotation-panel__placeholder-icon {\n color: #ccc;\n margin-bottom: 12px;\n}\n\n.udoc-viewer-root .udoc-annotation-panel__placeholder-icon svg {\n width: 48px;\n height: 48px;\n}\n\n.udoc-viewer-root .udoc-annotation-panel__placeholder-title {\n font-size: 14px;\n font-weight: 500;\n color: #666;\n margin-bottom: 4px;\n}\n\n.udoc-viewer-root .udoc-annotation-panel__placeholder-message {\n font-size: 12px;\n color: #999;\n}\n\n.udoc-viewer-root .udoc-annotation-panel__loading {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n color: #888;\n font-size: 13px;\n}\n\n/* Comments List */\n.udoc-viewer-root .udoc-comments-list {\n display: flex;\n flex-direction: column;\n}\n\n/* Page Group */\n.udoc-viewer-root .udoc-comments-page-group {\n border-bottom: 1px solid #e0e0e0;\n}\n\n.udoc-viewer-root .udoc-comments-page-group:last-child {\n border-bottom: none;\n}\n\n.udoc-viewer-root .udoc-comments-page-header {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 10px 12px;\n cursor: pointer;\n user-select: none;\n background: #f0f0f0;\n transition: background 0.15s;\n}\n\n.udoc-viewer-root .udoc-comments-page-header:hover {\n background: #e8e8e8;\n}\n\n.udoc-viewer-root .udoc-comments-page-header svg {\n width: 16px;\n height: 16px;\n color: #666;\n flex-shrink: 0;\n transition: transform 0.2s ease;\n}\n\n.udoc-viewer-root .udoc-comments-page-header span {\n font-size: 13px;\n font-weight: 500;\n color: #333;\n}\n\n.udoc-viewer-root .udoc-comments-page-count {\n margin-left: auto;\n padding: 2px 6px;\n background: #ddd;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 500;\n color: #666;\n}\n\n/* Collapsed state */\n.udoc-viewer-root .udoc-comments-page-group--collapsed .udoc-comments-page-header svg {\n transform: rotate(-90deg);\n}\n\n.udoc-viewer-root .udoc-comments-page-group--collapsed .udoc-comments-page-content {\n display: none;\n}\n\n/* Page Content */\n.udoc-viewer-root .udoc-comments-page-content {\n display: flex;\n flex-direction: column;\n}\n\n/* Comment Item */\n.udoc-viewer-root .udoc-comment-item {\n display: flex;\n gap: 8px;\n padding: 10px 12px;\n cursor: pointer;\n transition: background 0.15s;\n border-bottom: 1px solid #eee;\n}\n\n.udoc-viewer-root .udoc-comment-item:last-child {\n border-bottom: none;\n}\n\n.udoc-viewer-root .udoc-comment-item:hover {\n background: rgba(0, 102, 204, 0.05);\n}\n\n/* Reply indentation */\n.udoc-viewer-root .udoc-comment-reply {\n background: #fafafa;\n}\n\n.udoc-viewer-root .udoc-comment-depth-1 {\n padding-left: 28px;\n}\n\n.udoc-viewer-root .udoc-comment-depth-2 {\n padding-left: 44px;\n}\n\n.udoc-viewer-root .udoc-comment-depth-3 {\n padding-left: 60px;\n}\n\n/* Comment Icon */\n.udoc-viewer-root .udoc-comment-icon {\n flex-shrink: 0;\n width: 20px;\n height: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #888;\n}\n\n.udoc-viewer-root .udoc-comment-icon svg {\n width: 16px;\n height: 16px;\n}\n\n/* Comment Body */\n.udoc-viewer-root .udoc-comment-body {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n/* Comment Header */\n.udoc-viewer-root .udoc-comment-header {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-wrap: wrap;\n}\n\n.udoc-viewer-root .udoc-comment-author {\n font-size: 12px;\n font-weight: 600;\n color: #333;\n}\n\n/* Status Badge */\n.udoc-viewer-root .udoc-comment-status {\n padding: 1px 6px;\n border-radius: 8px;\n font-size: 10px;\n font-weight: 500;\n text-transform: capitalize;\n}\n\n.udoc-viewer-root .udoc-comment-status--accepted {\n background: #d4edda;\n color: #155724;\n}\n\n.udoc-viewer-root .udoc-comment-status--rejected {\n background: #f8d7da;\n color: #721c24;\n}\n\n.udoc-viewer-root .udoc-comment-status--completed {\n background: #cce5ff;\n color: #004085;\n}\n\n.udoc-viewer-root .udoc-comment-status--cancelled {\n background: #e2e3e5;\n color: #383d41;\n}\n\n.udoc-viewer-root .udoc-comment-status--marked {\n background: #fff3cd;\n color: #856404;\n}\n\n.udoc-viewer-root .udoc-comment-status--unmarked {\n background: #e2e3e5;\n color: #383d41;\n}\n\n/* Comment Contents */\n.udoc-viewer-root .udoc-comment-contents {\n font-size: 12px;\n color: #555;\n line-height: 1.4;\n white-space: pre-wrap;\n word-wrap: break-word;\n overflow: hidden;\n display: -webkit-box;\n -webkit-line-clamp: 3;\n line-clamp: 3;\n -webkit-box-orient: vertical;\n}\n\n/* Reply Toggle */\n.udoc-viewer-root .udoc-comment-toggle {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 8px;\n margin-top: 4px;\n border: none;\n border-radius: 4px;\n background: transparent;\n color: #0066cc;\n font-size: 11px;\n cursor: pointer;\n transition: background 0.15s;\n}\n\n.udoc-viewer-root .udoc-comment-toggle:hover {\n background: rgba(0, 102, 204, 0.1);\n}\n\n.udoc-viewer-root .udoc-comment-toggle svg {\n width: 12px;\n height: 12px;\n transition: transform 0.2s ease;\n}\n\n.udoc-viewer-root .udoc-comment-toggle--expanded svg {\n transform: rotate(90deg);\n}\n\n/* Replies Container */\n.udoc-viewer-root .udoc-comment-replies {\n display: flex;\n flex-direction: column;\n}\n\n.udoc-viewer-root .udoc-comment-replies--collapsed {\n display: none;\n}\n\n/* Annotation Highlight Animation */\n@keyframes udoc-annotation-pulse {\n 0% {\n box-shadow: 0 0 0 0 rgba(0, 102, 204, 0.7);\n }\n 50% {\n box-shadow: 0 0 0 8px rgba(0, 102, 204, 0.3);\n }\n 100% {\n box-shadow: 0 0 0 12px rgba(0, 102, 204, 0);\n }\n}\n\n.udoc-viewer-root .udoc-annotation--highlighted {\n animation: udoc-annotation-pulse 1.5s ease-out;\n outline: 2px solid #0066cc;\n outline-offset: 2px;\n border-radius: 2px;\n z-index: 10;\n}\n\n/* Highlight indicator for full-layer markup annotations */\n.udoc-viewer-root .udoc-annotation-highlight-indicator {\n position: absolute;\n box-sizing: border-box;\n pointer-events: none;\n animation: udoc-annotation-pulse 1.5s ease-out;\n outline: 2px solid #0066cc;\n outline-offset: 2px;\n border-radius: 2px;\n z-index: 10;\n}\n\n/* Mobile Panel Overlay */\n.udoc-viewer-root .udoc-panel-overlay {\n display: none;\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.3);\n z-index: 140;\n}\n\n/* ===== Responsive: Small Mobile (\u2264480px) ===== */\n@container udoc-viewer (max-width: 480px) {\n /* Make body-slot a positioning context */\n .udoc-viewer-root .udoc-body-slot {\n position: relative;\n }\n\n /* Collapse panels to slide-out drawers */\n .udoc-viewer-root .udoc-left-panel {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n width: 280px !important;\n z-index: 150;\n box-shadow: 4px 0 20px rgba(0, 0, 0, 0.15);\n transform: translateX(-100%);\n transition: transform 0.3s ease;\n }\n\n .udoc-viewer-root .udoc-left-panel:not(.udoc-left-panel--closed) {\n transform: translateX(0);\n }\n\n .udoc-viewer-root .udoc-left-panel--closed {\n width: 280px !important;\n transform: translateX(-100%);\n }\n\n .udoc-viewer-root .udoc-right-panel {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n width: 280px !important;\n z-index: 150;\n box-shadow: -4px 0 20px rgba(0, 0, 0, 0.15);\n transform: translateX(100%);\n transition: transform 0.3s ease;\n }\n\n .udoc-viewer-root .udoc-right-panel:not(.udoc-right-panel--closed) {\n transform: translateX(0);\n }\n\n .udoc-viewer-root .udoc-right-panel--closed {\n width: 280px !important;\n transform: translateX(100%);\n }\n\n /* Show overlay when panel is open */\n .udoc-viewer-root.udoc-panel-open .udoc-panel-overlay {\n display: block;\n }\n\n /* Convert floating bar to full-width bottom toolbar */\n .udoc-viewer-root .udoc-floating-toolbar {\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n transform: none;\n border-radius: 0;\n box-sizing: border-box;\n height: 40px;\n padding: 0 12px;\n gap: 8px;\n max-width: none;\n justify-content: center;\n box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);\n }\n\n /* Viewport scroll area needs padding for bottom toolbar */\n .udoc-viewer-root .udoc-viewport__scroll {\n padding-bottom: 40px;\n }\n\n /* Move watermark above bottom toolbar on mobile */\n .udoc-viewer-root .udoc-viewport__watermark {\n bottom: 48px;\n right: 10px;\n font-size: 11px;\n }\n\n /* Hide fullscreen button on mobile */\n .udoc-viewer-root .udoc-toolbar__btn--fullscreen {\n display: none;\n }\n\n /* Touch targets for mobile */\n .udoc-viewer-root .udoc-floating-toolbar__btn {\n padding: 6px;\n min-width: 28px;\n min-height: 28px;\n }\n\n .udoc-viewer-root .udoc-floating-toolbar__btn svg {\n width: 18px;\n height: 18px;\n }\n\n /* Larger panel tab buttons for touch */\n .udoc-viewer-root .udoc-left-panel__tabs {\n width: 44px;\n padding: 8px 0;\n }\n\n .udoc-viewer-root .udoc-left-panel__tab {\n width: 44px;\n height: 44px;\n }\n\n .udoc-viewer-root .udoc-left-panel__tab svg {\n width: 22px;\n height: 22px;\n }\n\n /* Toolbar adjustments */\n .udoc-viewer-root .udoc-toolbar {\n padding: 0 4px;\n gap: 4px;\n }\n\n .udoc-viewer-root .udoc-toolbar__btn {\n padding: 8px;\n }\n\n /* View mode menu - right align */\n .udoc-viewer-root .udoc-view-mode-menu__dropdown {\n left: auto;\n right: 0;\n }\n\n .udoc-viewer-root .udoc-zoom-dropdown__item {\n padding: 12px 16px;\n }\n\n .udoc-viewer-root .udoc-view-mode-menu__option {\n width: 36px;\n height: 36px;\n }\n}\n\n/* ===== Password Dialog ===== */\n.udoc-viewer-root .udoc-password-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 200;\n}\n\n.udoc-viewer-root .udoc-password-dialog {\n background: #fff;\n border-radius: 12px;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);\n padding: 24px;\n max-width: 360px;\n width: 90%;\n}\n\n.udoc-viewer-root .udoc-password-header {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 12px;\n}\n\n.udoc-viewer-root .udoc-password-icon {\n width: 32px;\n height: 32px;\n color: #666;\n flex-shrink: 0;\n}\n\n.udoc-viewer-root .udoc-password-title {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n color: #333;\n}\n\n.udoc-viewer-root .udoc-password-message {\n margin: 0 0 20px 0;\n font-size: 14px;\n color: #666;\n line-height: 1.5;\n}\n\n.udoc-viewer-root .udoc-password-form {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.udoc-viewer-root .udoc-password-input-wrapper {\n display: flex;\n align-items: center;\n border: 1px solid #ddd;\n border-radius: 8px;\n background: #fff;\n transition: border-color 0.15s, box-shadow 0.15s;\n}\n\n.udoc-viewer-root .udoc-password-input-wrapper:focus-within {\n border-color: #0066cc;\n box-shadow: 0 0 0 3px rgba(0, 102, 204, 0.15);\n}\n\n.udoc-viewer-root .udoc-password-input {\n flex: 1;\n padding: 12px 14px;\n border: none;\n border-radius: 8px 0 0 8px;\n background: transparent;\n font-size: 15px;\n color: #333;\n outline: none;\n}\n\n.udoc-viewer-root .udoc-password-input::placeholder {\n color: #999;\n}\n\n.udoc-viewer-root .udoc-password-input:disabled {\n background: #f5f5f5;\n color: #999;\n}\n\n.udoc-viewer-root .udoc-password-toggle {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 44px;\n height: 44px;\n border: none;\n background: transparent;\n color: #888;\n cursor: pointer;\n transition: color 0.15s;\n}\n\n.udoc-viewer-root .udoc-password-toggle:hover {\n color: #333;\n}\n\n.udoc-viewer-root .udoc-password-toggle svg {\n width: 20px;\n height: 20px;\n}\n\n.udoc-viewer-root .udoc-password-error {\n margin: 0;\n padding: 8px 12px;\n background: #fef2f2;\n border: 1px solid #fecaca;\n border-radius: 6px;\n font-size: 13px;\n color: #dc2626;\n}\n\n.udoc-viewer-root .udoc-password-submit {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 12px 20px;\n border: none;\n border-radius: 8px;\n background: #0066cc;\n color: #fff;\n font-size: 15px;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.15s;\n}\n\n.udoc-viewer-root .udoc-password-submit:hover:not(:disabled) {\n background: #0052a3;\n}\n\n.udoc-viewer-root .udoc-password-submit:disabled {\n background: #94a3b8;\n cursor: not-allowed;\n}\n\n.udoc-viewer-root .udoc-password-submit-spinner svg {\n width: 20px;\n height: 20px;\n}\n\n/* ===== Loading Overlay ===== */\n.udoc-viewer-root .udoc-loading-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(255, 255, 255, 0.95);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 180;\n backdrop-filter: blur(2px);\n}\n\n.udoc-viewer-root .udoc-loading-content {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 16px;\n padding: 24px;\n}\n\n.udoc-viewer-root .udoc-loading-spinner {\n width: 40px;\n height: 40px;\n color: #0066cc;\n}\n\n.udoc-viewer-root .udoc-loading-spinner svg {\n width: 100%;\n height: 100%;\n}\n\n.udoc-viewer-root .udoc-loading-progress-container {\n width: 240px;\n}\n\n.udoc-viewer-root .udoc-loading-progress-track {\n width: 100%;\n height: 6px;\n background: #e5e7eb;\n border-radius: 3px;\n overflow: hidden;\n}\n\n.udoc-viewer-root .udoc-loading-progress-fill {\n height: 100%;\n background: #0066cc;\n border-radius: 3px;\n width: 0%;\n transition: width 0.2s ease-out;\n}\n\n.udoc-viewer-root .udoc-loading-progress-fill--indeterminate {\n animation: udoc-loading-indeterminate 1.5s ease-in-out infinite;\n}\n\n@keyframes udoc-loading-indeterminate {\n 0% {\n transform: translateX(-100%);\n }\n 50% {\n transform: translateX(233%);\n }\n 100% {\n transform: translateX(-100%);\n }\n}\n\n.udoc-viewer-root .udoc-loading-progress-text {\n font-size: 13px;\n color: #666;\n text-align: center;\n}\n";
1
+ export declare const inlineStyles = ".udoc-viewer-root {\n display: flex;\n flex-direction: column;\n height: 100%;\n container-type: inline-size;\n container-name: udoc-viewer;\n}\n\n.udoc-viewer-root .udoc-toolbar-slot {\n flex: 0 0 auto;\n}\n\n.udoc-viewer-root .udoc-body-slot {\n flex: 1 1 auto;\n display: flex;\n overflow: hidden;\n}\n\n.udoc-viewer-root .udoc-left-panel-slot {\n flex: 0 0 auto;\n}\n\n.udoc-viewer-root .udoc-right-panel-slot {\n flex: 0 0 auto;\n}\n\n.udoc-viewer-root .udoc-viewport-slot {\n position: relative;\n flex: 1 1 auto;\n overflow: hidden;\n}\n\n.udoc-viewer-root .udoc-viewport {\n position: relative;\n width: 100%;\n height: 100%;\n background: #e0e0e0;\n}\n\n.udoc-viewer-root .udoc-viewport__scroll {\n width: 100%;\n height: 100%;\n overflow: auto;\n scrollbar-gutter: stable;\n}\n\n.udoc-viewer-root .udoc-viewport__container {\n position: relative;\n min-height: 100%;\n box-sizing: border-box;\n /* height set dynamically for virtual scrolling */\n}\n\n.udoc-viewer-root .udoc-viewport__watermark {\n position: absolute;\n right: 18px;\n bottom: 4px;\n padding: 2px 6px;\n font-size: 12px;\n font-weight: 500;\n color: rgba(0, 0, 0, 0.3);\n text-decoration: none;\n text-shadow: 0 1px 2px rgba(255, 255, 255, 0.5);\n z-index: 10;\n transition: color 0.15s ease;\n}\n\n.udoc-viewer-root .udoc-viewport__watermark:hover {\n color: rgba(0, 0, 0, 0.6);\n}\n\n/* Spread */\n.udoc-viewer-root .udoc-spread {\n display: flex;\n flex-direction: row;\n justify-content: flex-start;\n flex-shrink: 0;\n}\n\n.udoc-viewer-root .udoc-spread--hidden {\n display: none;\n}\n\n/* Page slot within spread */\n.udoc-viewer-root .udoc-spread__slot {\n display: flex;\n align-items: center;\n justify-content: center;\n background: white;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n}\n\n.udoc-viewer-root .udoc-viewport--seamless .udoc-spread__slot {\n box-shadow: none;\n}\n\n.udoc-viewer-root .udoc-spread__slot--empty {\n background: transparent;\n box-shadow: none;\n}\n\n.udoc-viewer-root .udoc-spread__canvas {\n display: block;\n}\n\n/* Floating Toolbar */\n.udoc-viewer-root .udoc-floating-toolbar {\n position: absolute;\n bottom: 24px;\n left: 50%;\n transform: translateX(-50%);\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 6px 10px;\n background: #fff;\n border-radius: 8px;\n box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);\n z-index: 100;\n}\n\n.udoc-viewer-root .udoc-floating-toolbar__section {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.udoc-viewer-root .udoc-floating-toolbar__divider {\n width: 1px;\n height: 20px;\n background: rgba(0, 0, 0, 0.15);\n margin: 0 4px;\n}\n\n.udoc-viewer-root .udoc-floating-toolbar__btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n padding: 0;\n border: none;\n border-radius: 4px;\n background: transparent;\n color: rgba(0, 0, 0, 0.7);\n cursor: pointer;\n}\n\n.udoc-viewer-root .udoc-floating-toolbar__btn:hover {\n background: rgba(0, 0, 0, 0.08);\n}\n\n.udoc-viewer-root .udoc-floating-toolbar__btn:active {\n background: rgba(0, 0, 0, 0.15);\n}\n\n.udoc-viewer-root .udoc-floating-toolbar__btn:disabled {\n color: rgba(0, 0, 0, 0.25);\n cursor: default;\n}\n\n.udoc-viewer-root .udoc-floating-toolbar__btn:disabled:hover {\n background: transparent;\n}\n\n.udoc-viewer-root .udoc-floating-toolbar__btn svg {\n width: 18px;\n height: 18px;\n}\n\n.udoc-viewer-root .udoc-floating-toolbar__page-info {\n display: flex;\n align-items: center;\n color: rgba(0, 0, 0, 0.8);\n font-size: 13px;\n}\n\n.udoc-viewer-root .udoc-floating-toolbar__page-input {\n width: 36px;\n padding: 2px 4px;\n border: 1px solid rgba(0, 0, 0, 0.15);\n border-radius: 4px;\n background: transparent;\n color: rgba(0, 0, 0, 0.8);\n font-size: 13px;\n text-align: center;\n}\n\n.udoc-viewer-root .udoc-floating-toolbar__page-input:focus {\n outline: none;\n border-color: rgba(0, 0, 0, 0.3);\n background: white;\n}\n\n.udoc-viewer-root .udoc-floating-toolbar__page-total {\n white-space: nowrap;\n}\n\n.udoc-viewer-root .udoc-floating-toolbar__zoom-level {\n min-width: 44px;\n color: rgba(0, 0, 0, 0.8);\n font-size: 13px;\n text-align: center;\n}\n\n.udoc-viewer-root .udoc-floating-toolbar__btn--active {\n background: rgba(0, 0, 0, 0.12);\n}\n\n/* Zoom Dropdown */\n.udoc-viewer-root .udoc-zoom-dropdown {\n position: relative;\n height: 28px;\n display: flex;\n align-items: center;\n}\n\n.udoc-viewer-root .udoc-zoom-dropdown__toggle {\n display: flex;\n align-items: center;\n gap: 0;\n height: 100%;\n border: 1px solid rgba(0, 0, 0, 0.15);\n border-radius: 4px;\n background: transparent;\n}\n\n.udoc-viewer-root .udoc-zoom-dropdown__toggle:focus-within {\n border-color: rgba(0, 0, 0, 0.3);\n background: white;\n}\n\n.udoc-viewer-root .udoc-zoom-dropdown__input {\n width: 44px;\n padding: 2px 4px;\n border: none;\n border-radius: 4px 0 0 4px;\n background: transparent;\n color: rgba(0, 0, 0, 0.8);\n font-size: 13px;\n text-align: center;\n}\n\n.udoc-viewer-root .udoc-zoom-dropdown__input:focus {\n outline: none;\n}\n\n.udoc-viewer-root .udoc-zoom-dropdown__chevron {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 2px 2px;\n border: none;\n border-left: 1px solid rgba(0, 0, 0, 0.1);\n border-radius: 0 4px 4px 0;\n background: transparent;\n color: rgba(0, 0, 0, 0.5);\n cursor: pointer;\n}\n\n.udoc-viewer-root .udoc-zoom-dropdown__chevron:hover {\n background: rgba(0, 0, 0, 0.08);\n color: rgba(0, 0, 0, 0.7);\n}\n\n.udoc-viewer-root .udoc-zoom-dropdown__chevron--active {\n background: rgba(0, 0, 0, 0.12);\n}\n\n.udoc-viewer-root .udoc-zoom-dropdown__chevron svg {\n width: 14px;\n height: 14px;\n}\n\n.udoc-viewer-root .udoc-zoom-dropdown__menu {\n position: absolute;\n bottom: calc(100% + 8px);\n left: 50%;\n transform: translateX(-50%);\n padding: 6px;\n background: #fff;\n border-radius: 8px;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);\n min-width: 100px;\n}\n\n.udoc-viewer-root .udoc-zoom-dropdown__section {\n display: flex;\n flex-direction: column;\n}\n\n.udoc-viewer-root .udoc-zoom-dropdown__divider {\n height: 1px;\n background: rgba(0, 0, 0, 0.1);\n margin: 6px 0;\n}\n\n.udoc-viewer-root .udoc-zoom-dropdown__item {\n display: block;\n width: 100%;\n padding: 6px 10px;\n border: none;\n border-radius: 4px;\n background: transparent;\n color: rgba(0, 0, 0, 0.8);\n font-size: 13px;\n text-align: left;\n cursor: pointer;\n white-space: nowrap;\n}\n\n.udoc-viewer-root .udoc-zoom-dropdown__item:hover {\n background: rgba(0, 0, 0, 0.08);\n}\n\n.udoc-viewer-root .udoc-zoom-dropdown__item--active {\n background: rgba(0, 102, 204, 0.15);\n color: #0066cc;\n}\n\n.udoc-viewer-root .udoc-zoom-dropdown__item--active:hover {\n background: rgba(0, 102, 204, 0.2);\n}\n\n/* View Mode Menu */\n.udoc-viewer-root .udoc-view-mode-menu {\n position: relative;\n height: 28px;\n display: flex;\n align-items: center;\n}\n\n.udoc-viewer-root .udoc-view-mode-menu__dropdown {\n position: absolute;\n bottom: calc(100% + 8px);\n left: 0;\n padding: 8px;\n background: #fff;\n border-radius: 8px;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);\n min-width: 160px;\n}\n\n.udoc-viewer-root .udoc-view-mode-menu__section {\n margin-bottom: 8px;\n}\n\n.udoc-viewer-root .udoc-view-mode-menu__section:last-child {\n margin-bottom: 0;\n}\n\n.udoc-viewer-root .udoc-view-mode-menu__title {\n font-size: 10px;\n font-weight: 600;\n text-transform: uppercase;\n color: rgba(0, 0, 0, 0.5);\n margin-bottom: 4px;\n padding: 0 4px;\n}\n\n.udoc-viewer-root .udoc-view-mode-menu__options {\n display: flex;\n gap: 2px;\n}\n\n.udoc-viewer-root .udoc-view-mode-menu__option {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n padding: 0;\n border: none;\n border-radius: 4px;\n background: transparent;\n color: rgba(0, 0, 0, 0.6);\n cursor: pointer;\n}\n\n.udoc-viewer-root .udoc-view-mode-menu__option:hover {\n background: rgba(0, 0, 0, 0.08);\n}\n\n.udoc-viewer-root .udoc-view-mode-menu__option--active {\n background: rgba(0, 102, 204, 0.15);\n color: #0066cc;\n}\n\n.udoc-viewer-root .udoc-view-mode-menu__option--active:hover {\n background: rgba(0, 102, 204, 0.2);\n}\n\n.udoc-viewer-root .udoc-view-mode-menu__option--disabled {\n color: rgba(0, 0, 0, 0.25);\n cursor: default;\n}\n\n.udoc-viewer-root .udoc-view-mode-menu__option--disabled:hover {\n background: transparent;\n}\n\n.udoc-viewer-root .udoc-view-mode-menu__option-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.udoc-viewer-root .udoc-view-mode-menu__option-icon svg {\n width: 20px;\n height: 20px;\n}\n\n/* Left Panel */\n.udoc-viewer-root .udoc-left-panel {\n position: relative;\n display: flex;\n width: 240px;\n height: 100%;\n background: #f5f5f5;\n border-right: 1px solid #ddd;\n transition: width 0.2s ease, opacity 0.2s ease;\n}\n\n.udoc-viewer-root .udoc-left-panel--closed {\n width: 0;\n overflow: hidden;\n border-right: none;\n}\n\n.udoc-viewer-root .udoc-left-panel__tabs {\n display: flex;\n flex-direction: column;\n width: 40px;\n background: #e8e8e8;\n border-right: 1px solid #ddd;\n}\n\n.udoc-viewer-root .udoc-left-panel__tab {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n padding: 0;\n border: none;\n background: transparent;\n color: #666;\n cursor: pointer;\n}\n\n.udoc-viewer-root .udoc-left-panel__tab:hover {\n background: rgba(0, 0, 0, 0.08);\n}\n\n.udoc-viewer-root .udoc-left-panel__tab--active {\n background: #f5f5f5;\n color: #333;\n border-right: 2px solid #0066cc;\n}\n\n.udoc-viewer-root .udoc-left-panel__tab svg {\n width: 20px;\n height: 20px;\n}\n\n.udoc-viewer-root .udoc-left-panel__content {\n flex: 1;\n overflow: hidden;\n}\n\n.udoc-viewer-root .udoc-left-panel__resize-handle {\n position: absolute;\n right: 0;\n top: 0;\n width: 4px;\n height: 100%;\n cursor: col-resize;\n background: transparent;\n z-index: 10;\n}\n\n.udoc-viewer-root .udoc-left-panel__resize-handle:hover,\n.udoc-viewer-root .udoc-left-panel--resizing .udoc-left-panel__resize-handle {\n background: rgba(0, 102, 204, 0.3);\n}\n\n.udoc-viewer-root .udoc-left-panel--resizing {\n transition: none;\n}\n\n/* Thumbnail Panel */\n.udoc-viewer-root .udoc-thumbnail-panel {\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 12px;\n height: 100%;\n overflow-y: auto;\n overflow-x: hidden;\n}\n\n.udoc-viewer-root .udoc-thumbnail-item {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n padding: 8px;\n border-radius: 4px;\n cursor: pointer;\n transition: background 0.15s ease;\n flex-shrink: 0;\n width: 100%;\n box-sizing: border-box;\n}\n\n.udoc-viewer-root .udoc-thumbnail-item:hover {\n background: rgba(0, 0, 0, 0.05);\n}\n\n.udoc-viewer-root .udoc-thumbnail-item--active {\n background: rgba(0, 102, 204, 0.1);\n outline: 2px solid #0066cc;\n outline-offset: -2px;\n}\n\n.udoc-viewer-root .udoc-thumbnail-item__canvas {\n display: block;\n max-width: calc(100% - 16px);\n background: white;\n box-shadow: 0 1px 4px rgba(0, 0, 0, 0.15);\n}\n\n.udoc-viewer-root .udoc-thumbnail-item__label {\n font-size: 11px;\n color: #666;\n text-align: center;\n}\n\n.udoc-viewer-root .udoc-thumbnail-item--active .udoc-thumbnail-item__label {\n color: #0066cc;\n font-weight: 500;\n}\n\n/* Outline Panel */\n.udoc-viewer-root .udoc-outline-panel {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow-y: auto;\n overflow-x: hidden;\n padding: 8px 0;\n}\n\n.udoc-viewer-root .udoc-outline-panel__loading,\n.udoc-viewer-root .udoc-outline-panel__empty {\n padding: 16px;\n color: #888;\n font-size: 13px;\n text-align: center;\n}\n\n.udoc-viewer-root .udoc-outline-item {\n display: flex;\n flex-direction: column;\n}\n\n.udoc-viewer-root .udoc-outline-item__header {\n display: flex;\n align-items: center;\n padding: 6px 12px 6px 8px;\n gap: 4px;\n min-height: 28px;\n}\n\n.udoc-viewer-root .udoc-outline-item__header--clickable {\n cursor: pointer;\n}\n\n.udoc-viewer-root .udoc-outline-item__header--clickable:hover {\n background: rgba(0, 0, 0, 0.05);\n}\n\n.udoc-viewer-root .udoc-outline-item__header--active {\n background: rgba(0, 102, 204, 0.1);\n}\n\n.udoc-viewer-root .udoc-outline-item__header--active .udoc-outline-item__title {\n color: #0066cc;\n font-weight: 500;\n}\n\n.udoc-viewer-root .udoc-outline-item__toggle {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n padding: 0;\n border: none;\n background: transparent;\n color: #666;\n cursor: pointer;\n flex-shrink: 0;\n transition: transform 0.15s ease;\n}\n\n.udoc-viewer-root .udoc-outline-item__toggle:hover {\n color: #333;\n}\n\n.udoc-viewer-root .udoc-outline-item__toggle--expanded {\n transform: rotate(90deg);\n}\n\n.udoc-viewer-root .udoc-outline-item__spacer {\n width: 16px;\n flex-shrink: 0;\n}\n\n.udoc-viewer-root .udoc-outline-item__title {\n font-size: 13px;\n color: #333;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n flex: 1;\n}\n\n/* .udoc-outline-item__children: Indentation is handled via padding-left on header */\n\n.udoc-viewer-root .udoc-toolbar {\n display: flex;\n align-items: center;\n height: 40px;\n padding: 0 8px;\n background: #f5f5f5;\n border-bottom: 1px solid #ddd;\n}\n\n.udoc-viewer-root .udoc-toolbar__left,\n.udoc-viewer-root .udoc-toolbar__right {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.udoc-viewer-root .udoc-toolbar__spacer {\n flex: 1;\n}\n\n.udoc-viewer-root .udoc-toolbar__btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n padding: 0;\n border: none;\n border-radius: 4px;\n background: transparent;\n color: #555;\n cursor: pointer;\n}\n\n.udoc-viewer-root .udoc-toolbar__btn:hover {\n background: rgba(0, 0, 0, 0.08);\n}\n\n.udoc-viewer-root .udoc-toolbar__btn:active {\n background: rgba(0, 0, 0, 0.12);\n}\n\n.udoc-viewer-root .udoc-toolbar__btn svg {\n width: 20px;\n height: 20px;\n}\n\n/* Right Panel */\n.udoc-viewer-root .udoc-right-panel {\n position: relative;\n display: flex;\n flex-direction: column;\n width: 300px;\n height: 100%;\n background: #f5f5f5;\n border-left: 1px solid #ddd;\n transition: width 0.2s ease, opacity 0.2s ease;\n}\n\n.udoc-viewer-root .udoc-right-panel--closed {\n width: 0;\n overflow: hidden;\n border-left: none;\n}\n\n.udoc-viewer-root .udoc-right-panel__resize-handle {\n position: absolute;\n left: 0;\n top: 0;\n width: 4px;\n height: 100%;\n cursor: col-resize;\n background: transparent;\n z-index: 10;\n}\n\n.udoc-viewer-root .udoc-right-panel__resize-handle:hover,\n.udoc-viewer-root .udoc-right-panel--resizing .udoc-right-panel__resize-handle {\n background: rgba(0, 102, 204, 0.3);\n}\n\n.udoc-viewer-root .udoc-right-panel--resizing {\n transition: none;\n}\n\n.udoc-viewer-root .udoc-right-panel__content {\n flex: 1;\n overflow: auto;\n}\n\n/* Text Layer (for text selection) */\n.udoc-viewer-root .udoc-spread__text-layer {\n position: absolute;\n overflow: hidden;\n /* user-select: none prevents selection from starting/extending in gaps */\n user-select: none;\n pointer-events: auto;\n z-index: 1;\n}\n\n.udoc-viewer-root .udoc-text-span {\n position: absolute;\n color: transparent;\n white-space: pre;\n line-height: 1;\n font-family: sans-serif;\n /* Allow selection on actual text spans */\n user-select: text;\n}\n\n.udoc-viewer-root .udoc-text-span::selection {\n background: rgba(0, 120, 215, 0.3);\n}\n\n/* Annotation Layer */\n.udoc-viewer-root .udoc-spread__annotation-layer {\n position: absolute;\n pointer-events: none;\n z-index: 2;\n}\n\n/* Base annotation */\n.udoc-viewer-root .udoc-annotation {\n position: absolute;\n box-sizing: border-box;\n}\n\n/* Link annotation */\n.udoc-viewer-root .udoc-annotation--link {\n pointer-events: auto;\n cursor: pointer;\n transition: background-color 0.15s ease;\n}\n\n.udoc-viewer-root .udoc-annotation--link:hover {\n background-color: rgba(0, 102, 204, 0.15);\n}\n\n/* Highlight annotation */\n.udoc-viewer-root .udoc-annotation--highlight {\n pointer-events: none;\n}\n\n.udoc-viewer-root .udoc-annotation__quad {\n mix-blend-mode: multiply;\n}\n\n/* Underline annotation */\n.udoc-viewer-root .udoc-annotation--underline {\n pointer-events: none;\n}\n\n/* StrikeOut annotation */\n.udoc-viewer-root .udoc-annotation--strikeout {\n pointer-events: none;\n}\n\n/* Squiggly annotation */\n.udoc-viewer-root .udoc-annotation--squiggly {\n pointer-events: none;\n}\n\n/* Text (sticky note) annotation */\n.udoc-viewer-root .udoc-annotation--text {\n pointer-events: auto;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: filter 0.15s ease;\n}\n\n.udoc-viewer-root .udoc-annotation--text:hover {\n filter: brightness(1.1) drop-shadow(0 1px 2px rgba(0, 0, 0, 0.3));\n}\n\n.udoc-viewer-root .udoc-annotation--text svg {\n width: 100%;\n height: 100%;\n}\n\n/* Annotation popup */\n.udoc-viewer-root .udoc-annotation-popup {\n position: absolute;\n z-index: 100;\n min-width: 200px;\n max-width: 300px;\n background: #ffffc0;\n border: 1px solid #d4d4a0;\n border-radius: 4px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);\n font-size: 12px;\n color: #333;\n pointer-events: auto;\n}\n\n.udoc-viewer-root .udoc-annotation-popup__header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 6px 8px;\n background: #f0f0c0;\n border-bottom: 1px solid #d4d4a0;\n border-radius: 4px 4px 0 0;\n}\n\n.udoc-viewer-root .udoc-annotation-popup__author {\n font-weight: 600;\n color: #555;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.udoc-viewer-root .udoc-annotation-popup__close {\n width: 16px;\n height: 16px;\n border: none;\n background: transparent;\n cursor: pointer;\n padding: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0.6;\n flex-shrink: 0;\n margin-left: 8px;\n}\n\n.udoc-viewer-root .udoc-annotation-popup__close:hover {\n opacity: 1;\n}\n\n.udoc-viewer-root .udoc-annotation-popup__close svg {\n width: 12px;\n height: 12px;\n}\n\n.udoc-viewer-root .udoc-annotation-popup__content {\n padding: 8px;\n white-space: pre-wrap;\n word-wrap: break-word;\n max-height: 200px;\n overflow-y: auto;\n}\n\n/* FreeText annotation */\n.udoc-viewer-root .udoc-annotation--freetext {\n pointer-events: auto;\n overflow: hidden;\n font-size: 12px;\n padding: 2px;\n}\n\n/* Stamp annotation */\n.udoc-viewer-root .udoc-annotation--stamp {\n pointer-events: none;\n}\n\n/* Caret annotation - rendered via SVG, minimal styling needed */\n.udoc-viewer-root .udoc-annotation--caret {\n pointer-events: none;\n}\n\n/* Shape annotations - rendered via SVG overlay */\n.udoc-viewer-root .udoc-annotation--line,\n.udoc-viewer-root .udoc-annotation--square,\n.udoc-viewer-root .udoc-annotation--circle,\n.udoc-viewer-root .udoc-annotation--polygon,\n.udoc-viewer-root .udoc-annotation--polyLine,\n.udoc-viewer-root .udoc-annotation--ink {\n pointer-events: none;\n}\n\n/* Redact annotation */\n.udoc-viewer-root .udoc-annotation--redact {\n pointer-events: none;\n}\n\n/* Annotation Panel */\n.udoc-viewer-root .udoc-annotation-panel {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.udoc-viewer-root .udoc-annotation-panel__placeholder {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n padding: 32px 16px;\n text-align: center;\n color: #888;\n}\n\n.udoc-viewer-root .udoc-annotation-panel__placeholder-icon {\n color: #ccc;\n margin-bottom: 12px;\n}\n\n.udoc-viewer-root .udoc-annotation-panel__placeholder-icon svg {\n width: 48px;\n height: 48px;\n}\n\n.udoc-viewer-root .udoc-annotation-panel__placeholder-title {\n font-size: 14px;\n font-weight: 500;\n color: #666;\n margin-bottom: 4px;\n}\n\n.udoc-viewer-root .udoc-annotation-panel__placeholder-message {\n font-size: 12px;\n color: #999;\n}\n\n.udoc-viewer-root .udoc-annotation-panel__loading {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n color: #888;\n font-size: 13px;\n}\n\n/* Comments List */\n.udoc-viewer-root .udoc-comments-list {\n display: flex;\n flex-direction: column;\n}\n\n/* Page Group */\n.udoc-viewer-root .udoc-comments-page-group {\n border-bottom: 1px solid #e0e0e0;\n}\n\n.udoc-viewer-root .udoc-comments-page-group:last-child {\n border-bottom: none;\n}\n\n.udoc-viewer-root .udoc-comments-page-header {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 10px 12px;\n cursor: pointer;\n user-select: none;\n background: #f0f0f0;\n transition: background 0.15s;\n}\n\n.udoc-viewer-root .udoc-comments-page-header:hover {\n background: #e8e8e8;\n}\n\n.udoc-viewer-root .udoc-comments-page-header svg {\n width: 16px;\n height: 16px;\n color: #666;\n flex-shrink: 0;\n transition: transform 0.2s ease;\n}\n\n.udoc-viewer-root .udoc-comments-page-header span {\n font-size: 13px;\n font-weight: 500;\n color: #333;\n}\n\n.udoc-viewer-root .udoc-comments-page-count {\n margin-left: auto;\n padding: 2px 6px;\n background: #ddd;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 500;\n color: #666;\n}\n\n/* Collapsed state */\n.udoc-viewer-root .udoc-comments-page-group--collapsed .udoc-comments-page-header svg {\n transform: rotate(-90deg);\n}\n\n.udoc-viewer-root .udoc-comments-page-group--collapsed .udoc-comments-page-content {\n display: none;\n}\n\n/* Page Content */\n.udoc-viewer-root .udoc-comments-page-content {\n display: flex;\n flex-direction: column;\n}\n\n/* Comment Item */\n.udoc-viewer-root .udoc-comment-item {\n display: flex;\n gap: 8px;\n padding: 10px 12px;\n cursor: pointer;\n transition: background 0.15s;\n border-bottom: 1px solid #eee;\n}\n\n.udoc-viewer-root .udoc-comment-item:last-child {\n border-bottom: none;\n}\n\n.udoc-viewer-root .udoc-comment-item:hover {\n background: rgba(0, 102, 204, 0.05);\n}\n\n/* Reply indentation */\n.udoc-viewer-root .udoc-comment-reply {\n background: #fafafa;\n}\n\n.udoc-viewer-root .udoc-comment-depth-1 {\n padding-left: 28px;\n}\n\n.udoc-viewer-root .udoc-comment-depth-2 {\n padding-left: 44px;\n}\n\n.udoc-viewer-root .udoc-comment-depth-3 {\n padding-left: 60px;\n}\n\n/* Comment Icon */\n.udoc-viewer-root .udoc-comment-icon {\n flex-shrink: 0;\n width: 20px;\n height: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #888;\n}\n\n.udoc-viewer-root .udoc-comment-icon svg {\n width: 16px;\n height: 16px;\n}\n\n/* Comment Body */\n.udoc-viewer-root .udoc-comment-body {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n/* Comment Header */\n.udoc-viewer-root .udoc-comment-header {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-wrap: wrap;\n}\n\n.udoc-viewer-root .udoc-comment-author {\n font-size: 12px;\n font-weight: 600;\n color: #333;\n}\n\n/* Status Badge */\n.udoc-viewer-root .udoc-comment-status {\n padding: 1px 6px;\n border-radius: 8px;\n font-size: 10px;\n font-weight: 500;\n text-transform: capitalize;\n}\n\n.udoc-viewer-root .udoc-comment-status--accepted {\n background: #d4edda;\n color: #155724;\n}\n\n.udoc-viewer-root .udoc-comment-status--rejected {\n background: #f8d7da;\n color: #721c24;\n}\n\n.udoc-viewer-root .udoc-comment-status--completed {\n background: #cce5ff;\n color: #004085;\n}\n\n.udoc-viewer-root .udoc-comment-status--cancelled {\n background: #e2e3e5;\n color: #383d41;\n}\n\n.udoc-viewer-root .udoc-comment-status--marked {\n background: #fff3cd;\n color: #856404;\n}\n\n.udoc-viewer-root .udoc-comment-status--unmarked {\n background: #e2e3e5;\n color: #383d41;\n}\n\n/* Comment Contents */\n.udoc-viewer-root .udoc-comment-contents {\n font-size: 12px;\n color: #555;\n line-height: 1.4;\n white-space: pre-wrap;\n word-wrap: break-word;\n overflow: hidden;\n display: -webkit-box;\n -webkit-line-clamp: 3;\n line-clamp: 3;\n -webkit-box-orient: vertical;\n}\n\n/* Reply Toggle */\n.udoc-viewer-root .udoc-comment-toggle {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 8px;\n margin-top: 4px;\n border: none;\n border-radius: 4px;\n background: transparent;\n color: #0066cc;\n font-size: 11px;\n cursor: pointer;\n transition: background 0.15s;\n}\n\n.udoc-viewer-root .udoc-comment-toggle:hover {\n background: rgba(0, 102, 204, 0.1);\n}\n\n.udoc-viewer-root .udoc-comment-toggle svg {\n width: 12px;\n height: 12px;\n transition: transform 0.2s ease;\n}\n\n.udoc-viewer-root .udoc-comment-toggle--expanded svg {\n transform: rotate(90deg);\n}\n\n/* Replies Container */\n.udoc-viewer-root .udoc-comment-replies {\n display: flex;\n flex-direction: column;\n}\n\n.udoc-viewer-root .udoc-comment-replies--collapsed {\n display: none;\n}\n\n/* Annotation Highlight Animation */\n@keyframes udoc-annotation-pulse {\n 0% {\n box-shadow: 0 0 0 0 rgba(0, 102, 204, 0.7);\n }\n 50% {\n box-shadow: 0 0 0 8px rgba(0, 102, 204, 0.3);\n }\n 100% {\n box-shadow: 0 0 0 12px rgba(0, 102, 204, 0);\n }\n}\n\n.udoc-viewer-root .udoc-annotation--highlighted {\n animation: udoc-annotation-pulse 1.5s ease-out;\n outline: 2px solid #0066cc;\n outline-offset: 2px;\n border-radius: 2px;\n z-index: 10;\n}\n\n/* Highlight indicator for full-layer markup annotations */\n.udoc-viewer-root .udoc-annotation-highlight-indicator {\n position: absolute;\n box-sizing: border-box;\n pointer-events: none;\n animation: udoc-annotation-pulse 1.5s ease-out;\n outline: 2px solid #0066cc;\n outline-offset: 2px;\n border-radius: 2px;\n z-index: 10;\n}\n\n/* Mobile Panel Overlay */\n.udoc-viewer-root .udoc-panel-overlay {\n display: none;\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.3);\n z-index: 140;\n}\n\n/* ===== Responsive: Small Mobile (\u2264480px) ===== */\n@container udoc-viewer (max-width: 480px) {\n /* Make body-slot a positioning context */\n .udoc-viewer-root .udoc-body-slot {\n position: relative;\n }\n\n /* Collapse panels to slide-out drawers */\n .udoc-viewer-root .udoc-left-panel {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n width: 280px !important;\n z-index: 150;\n box-shadow: 4px 0 20px rgba(0, 0, 0, 0.15);\n transform: translateX(-100%);\n transition: transform 0.3s ease;\n }\n\n .udoc-viewer-root .udoc-left-panel:not(.udoc-left-panel--closed) {\n transform: translateX(0);\n }\n\n .udoc-viewer-root .udoc-left-panel--closed {\n width: 280px !important;\n transform: translateX(-100%);\n }\n\n .udoc-viewer-root .udoc-right-panel {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n width: 280px !important;\n z-index: 150;\n box-shadow: -4px 0 20px rgba(0, 0, 0, 0.15);\n transform: translateX(100%);\n transition: transform 0.3s ease;\n }\n\n .udoc-viewer-root .udoc-right-panel:not(.udoc-right-panel--closed) {\n transform: translateX(0);\n }\n\n .udoc-viewer-root .udoc-right-panel--closed {\n width: 280px !important;\n transform: translateX(100%);\n }\n\n /* Show overlay when panel is open */\n .udoc-viewer-root.udoc-panel-open .udoc-panel-overlay {\n display: block;\n }\n\n /* Convert floating bar to full-width bottom toolbar */\n .udoc-viewer-root .udoc-floating-toolbar {\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n transform: none;\n border-radius: 0;\n box-sizing: border-box;\n height: 40px;\n padding: 0 12px;\n gap: 8px;\n max-width: none;\n justify-content: center;\n box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);\n }\n\n /* Viewport scroll area needs padding for bottom toolbar */\n .udoc-viewer-root .udoc-viewport__scroll {\n padding-bottom: 40px;\n }\n\n /* Move watermark above bottom toolbar on mobile */\n .udoc-viewer-root .udoc-viewport__watermark {\n bottom: 48px;\n right: 10px;\n font-size: 11px;\n }\n\n /* Hide fullscreen button on mobile */\n .udoc-viewer-root .udoc-toolbar__btn--fullscreen {\n display: none;\n }\n\n /* Touch targets for mobile */\n .udoc-viewer-root .udoc-floating-toolbar__btn {\n padding: 6px;\n min-width: 28px;\n min-height: 28px;\n }\n\n .udoc-viewer-root .udoc-floating-toolbar__btn svg {\n width: 18px;\n height: 18px;\n }\n\n /* Larger panel tab buttons for touch */\n .udoc-viewer-root .udoc-left-panel__tabs {\n width: 44px;\n padding: 8px 0;\n }\n\n .udoc-viewer-root .udoc-left-panel__tab {\n width: 44px;\n height: 44px;\n }\n\n .udoc-viewer-root .udoc-left-panel__tab svg {\n width: 22px;\n height: 22px;\n }\n\n /* Toolbar adjustments */\n .udoc-viewer-root .udoc-toolbar {\n padding: 0 4px;\n gap: 4px;\n }\n\n .udoc-viewer-root .udoc-toolbar__btn {\n padding: 8px;\n }\n\n /* View mode menu - right align */\n .udoc-viewer-root .udoc-view-mode-menu__dropdown {\n left: auto;\n right: 0;\n }\n\n .udoc-viewer-root .udoc-zoom-dropdown__item {\n padding: 12px 16px;\n }\n\n .udoc-viewer-root .udoc-view-mode-menu__option {\n width: 36px;\n height: 36px;\n }\n}\n\n/* ===== Password Dialog ===== */\n.udoc-viewer-root .udoc-password-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 200;\n}\n\n.udoc-viewer-root .udoc-password-dialog {\n background: #fff;\n border-radius: 12px;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);\n padding: 24px;\n max-width: 360px;\n width: 90%;\n}\n\n.udoc-viewer-root .udoc-password-header {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 12px;\n}\n\n.udoc-viewer-root .udoc-password-icon {\n width: 32px;\n height: 32px;\n color: #666;\n flex-shrink: 0;\n}\n\n.udoc-viewer-root .udoc-password-title {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n color: #333;\n}\n\n.udoc-viewer-root .udoc-password-message {\n margin: 0 0 20px 0;\n font-size: 14px;\n color: #666;\n line-height: 1.5;\n}\n\n.udoc-viewer-root .udoc-password-form {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.udoc-viewer-root .udoc-password-input-wrapper {\n display: flex;\n align-items: center;\n border: 1px solid #ddd;\n border-radius: 8px;\n background: #fff;\n transition: border-color 0.15s, box-shadow 0.15s;\n}\n\n.udoc-viewer-root .udoc-password-input-wrapper:focus-within {\n border-color: #0066cc;\n box-shadow: 0 0 0 3px rgba(0, 102, 204, 0.15);\n}\n\n.udoc-viewer-root .udoc-password-input {\n flex: 1;\n padding: 12px 14px;\n border: none;\n border-radius: 8px 0 0 8px;\n background: transparent;\n font-size: 15px;\n color: #333;\n outline: none;\n}\n\n.udoc-viewer-root .udoc-password-input::placeholder {\n color: #999;\n}\n\n.udoc-viewer-root .udoc-password-input:disabled {\n background: #f5f5f5;\n color: #999;\n}\n\n.udoc-viewer-root .udoc-password-toggle {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 44px;\n height: 44px;\n border: none;\n background: transparent;\n color: #888;\n cursor: pointer;\n transition: color 0.15s;\n}\n\n.udoc-viewer-root .udoc-password-toggle:hover {\n color: #333;\n}\n\n.udoc-viewer-root .udoc-password-toggle svg {\n width: 20px;\n height: 20px;\n}\n\n.udoc-viewer-root .udoc-password-error {\n margin: 0;\n padding: 8px 12px;\n background: #fef2f2;\n border: 1px solid #fecaca;\n border-radius: 6px;\n font-size: 13px;\n color: #dc2626;\n}\n\n.udoc-viewer-root .udoc-password-submit {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 12px 20px;\n border: none;\n border-radius: 8px;\n background: #0066cc;\n color: #fff;\n font-size: 15px;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.15s;\n}\n\n.udoc-viewer-root .udoc-password-submit:hover:not(:disabled) {\n background: #0052a3;\n}\n\n.udoc-viewer-root .udoc-password-submit:disabled {\n background: #94a3b8;\n cursor: not-allowed;\n}\n\n.udoc-viewer-root .udoc-password-submit-spinner svg {\n width: 20px;\n height: 20px;\n}\n\n/* ===== Loading Overlay ===== */\n.udoc-viewer-root .udoc-loading-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(255, 255, 255, 0.95);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 180;\n backdrop-filter: blur(2px);\n}\n\n.udoc-viewer-root .udoc-loading-content {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 16px;\n padding: 24px;\n}\n\n.udoc-viewer-root .udoc-loading-spinner {\n width: 40px;\n height: 40px;\n color: #0066cc;\n}\n\n.udoc-viewer-root .udoc-loading-spinner svg {\n width: 100%;\n height: 100%;\n}\n\n.udoc-viewer-root .udoc-loading-progress-container {\n width: 240px;\n}\n\n.udoc-viewer-root .udoc-loading-progress-track {\n width: 100%;\n height: 6px;\n background: #e5e7eb;\n border-radius: 3px;\n overflow: hidden;\n}\n\n.udoc-viewer-root .udoc-loading-progress-fill {\n height: 100%;\n background: #0066cc;\n border-radius: 3px;\n width: 0%;\n transition: width 0.2s ease-out;\n}\n\n.udoc-viewer-root .udoc-loading-progress-fill--indeterminate {\n animation: udoc-loading-indeterminate 1.5s ease-in-out infinite;\n}\n\n@keyframes udoc-loading-indeterminate {\n 0% {\n transform: translateX(-100%);\n }\n 50% {\n transform: translateX(233%);\n }\n 100% {\n transform: translateX(-100%);\n }\n}\n\n.udoc-viewer-root .udoc-loading-progress-text {\n font-size: 13px;\n color: #666;\n text-align: center;\n}\n";
2
2
  //# sourceMappingURL=styles-inline.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"styles-inline.d.ts","sourceRoot":"","sources":["../../../../src/ui/viewer/styles-inline.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,YAAY,+wlCAkjDxB,CAAC"}
1
+ {"version":3,"file":"styles-inline.d.ts","sourceRoot":"","sources":["../../../../src/ui/viewer/styles-inline.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,YAAY,y3mCA0kDxB,CAAC"}
@@ -719,11 +719,35 @@ export const inlineStyles = `.udoc-viewer-root {
719
719
  overflow: auto;
720
720
  }
721
721
 
722
+ /* Text Layer (for text selection) */
723
+ .udoc-viewer-root .udoc-spread__text-layer {
724
+ position: absolute;
725
+ overflow: hidden;
726
+ /* user-select: none prevents selection from starting/extending in gaps */
727
+ user-select: none;
728
+ pointer-events: auto;
729
+ z-index: 1;
730
+ }
731
+
732
+ .udoc-viewer-root .udoc-text-span {
733
+ position: absolute;
734
+ color: transparent;
735
+ white-space: pre;
736
+ line-height: 1;
737
+ font-family: sans-serif;
738
+ /* Allow selection on actual text spans */
739
+ user-select: text;
740
+ }
741
+
742
+ .udoc-viewer-root .udoc-text-span::selection {
743
+ background: rgba(0, 120, 215, 0.3);
744
+ }
745
+
722
746
  /* Annotation Layer */
723
747
  .udoc-viewer-root .udoc-spread__annotation-layer {
724
748
  position: absolute;
725
749
  pointer-events: none;
726
- z-index: 1;
750
+ z-index: 2;
727
751
  }
728
752
 
729
753
  /* Base annotation */
@@ -1 +1 @@
1
- {"version":3,"file":"styles-inline.js","sourceRoot":"","sources":["../../../../src/ui/viewer/styles-inline.ts"],"names":[],"mappings":"AAAA,0DAA0D;AAC1D,MAAM,CAAC,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkjD3B,CAAC"}
1
+ {"version":3,"file":"styles-inline.js","sourceRoot":"","sources":["../../../../src/ui/viewer/styles-inline.ts"],"names":[],"mappings":"AAAA,0DAA0D;AAC1D,MAAM,CAAC,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0kD3B,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Text selection layer module.
3
+ */
4
+ export type { TextRun, PositionedGlyph, TextTransform } from "./types";
5
+ export { renderTextToLayer } from "./render";
6
+ export { attachSelectionController } from "./selection";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/ui/viewer/text/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,YAAY,EAAE,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { renderTextToLayer } from "./render";
2
+ export { attachSelectionController } from "./selection";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/ui/viewer/text/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Text layer rendering for text selection.
3
+ *
4
+ * Creates invisible text spans positioned over the rendered page,
5
+ * allowing native browser text selection.
6
+ */
7
+ import type { TextRun } from "./types";
8
+ /**
9
+ * Render text runs to a text layer element.
10
+ *
11
+ * Creates positioned, invisible text spans that enable native browser selection.
12
+ *
13
+ * @param layer - The text layer element to render into
14
+ * @param textRuns - Text runs with position and font information
15
+ * @param scale - Scale factor (pointsToPixels * zoom)
16
+ * @param pageHeight - Page height in points (unused, kept for API compatibility)
17
+ */
18
+ export declare function renderTextToLayer(layer: HTMLDivElement, textRuns: TextRun[], scale: number, _pageHeight: number): void;
19
+ //# sourceMappingURL=render.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../../../src/ui/viewer/text/render.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAmBvC;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,cAAc,EACrB,QAAQ,EAAE,OAAO,EAAE,EACnB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,GAClB,IAAI,CAoJN"}
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Render text runs to a text layer element.
3
+ *
4
+ * Creates positioned, invisible text spans that enable native browser selection.
5
+ *
6
+ * @param layer - The text layer element to render into
7
+ * @param textRuns - Text runs with position and font information
8
+ * @param scale - Scale factor (pointsToPixels * zoom)
9
+ * @param pageHeight - Page height in points (unused, kept for API compatibility)
10
+ */
11
+ export function renderTextToLayer(layer, textRuns, scale, _pageHeight) {
12
+ // Clear existing content
13
+ layer.innerHTML = "";
14
+ if (textRuns.length === 0)
15
+ return;
16
+ // First pass: calculate positions and detect line boundaries
17
+ const processedRuns = [];
18
+ for (const run of textRuns) {
19
+ if (!run.text || run.glyphs.length === 0)
20
+ continue;
21
+ const { transform, fontSize } = run;
22
+ const effectiveScaleX = Math.sqrt(transform.scaleX * transform.scaleX + transform.skewY * transform.skewY);
23
+ const effectiveScaleY = Math.sqrt(transform.scaleY * transform.scaleY + transform.skewX * transform.skewX);
24
+ const scaledFontSize = fontSize * effectiveScaleY * scale;
25
+ const x = transform.translateX * scale;
26
+ const y = transform.translateY * scale;
27
+ processedRuns.push({
28
+ run,
29
+ y,
30
+ x,
31
+ scaledFontSize,
32
+ effectiveScaleX,
33
+ effectiveScaleY,
34
+ isEndOfLine: false, // Will be set in the next pass
35
+ spanHeight: scaledFontSize, // Will be adjusted in the next pass
36
+ });
37
+ }
38
+ if (processedRuns.length === 0)
39
+ return;
40
+ // Sort by Y position (top to bottom), then by X position (left to right)
41
+ processedRuns.sort((a, b) => {
42
+ const yDiff = a.y - b.y;
43
+ // If Y positions are within half a line height, consider them on the same line
44
+ const lineThreshold = Math.min(a.scaledFontSize, b.scaledFontSize) * 0.5;
45
+ if (Math.abs(yDiff) < lineThreshold) {
46
+ return a.x - b.x;
47
+ }
48
+ return yDiff;
49
+ });
50
+ // Mark end-of-line runs and calculate span heights to fill gaps
51
+ for (let i = 0; i < processedRuns.length - 1; i++) {
52
+ const current = processedRuns[i];
53
+ const next = processedRuns[i + 1];
54
+ const lineThreshold = current.scaledFontSize * 0.5;
55
+ // If next run is on a different line, current is end of line
56
+ if (Math.abs(next.y - current.y) >= lineThreshold) {
57
+ current.isEndOfLine = true;
58
+ // Calculate height to cover gap to next line
59
+ // From current top (y - ascent) to next line's top (nextY - nextAscent)
60
+ const currentTop = current.y - current.scaledFontSize * 0.8;
61
+ const nextTop = next.y - next.scaledFontSize * 0.8;
62
+ const gapHeight = nextTop - currentTop;
63
+ // Use calculated gap or at least 1.2x font size
64
+ current.spanHeight = Math.max(gapHeight, current.scaledFontSize * 1.2);
65
+ }
66
+ }
67
+ // Last run is always end of line, use generous height
68
+ const lastRun = processedRuns[processedRuns.length - 1];
69
+ lastRun.isEndOfLine = true;
70
+ lastRun.spanHeight = lastRun.scaledFontSize * 1.5;
71
+ // For all runs on the same line, extend their height to match the end-of-line run
72
+ let lineEndIndex = 0;
73
+ for (let i = 0; i < processedRuns.length; i++) {
74
+ if (processedRuns[i].isEndOfLine) {
75
+ const lineHeight = processedRuns[i].spanHeight;
76
+ // Apply this height to all runs from lineEndIndex to i
77
+ for (let j = lineEndIndex; j <= i; j++) {
78
+ processedRuns[j].spanHeight = lineHeight;
79
+ }
80
+ lineEndIndex = i + 1;
81
+ }
82
+ }
83
+ // Collect spans that need width scaling
84
+ const pendingSpans = [];
85
+ for (const processed of processedRuns) {
86
+ const { run, scaledFontSize, effectiveScaleX, isEndOfLine, spanHeight } = processed;
87
+ const { transform, glyphs } = run;
88
+ // Create span for this text run
89
+ const span = document.createElement("span");
90
+ span.className = "udoc-text-span";
91
+ // Add newline only at end of lines for proper line breaks when copying
92
+ const text = run.text ?? "";
93
+ span.textContent = isEndOfLine ? text + "\n" : text;
94
+ // Calculate the actual text width from glyph advances
95
+ const lastGlyph = glyphs[glyphs.length - 1];
96
+ const textWidthInTextSpace = lastGlyph.x + lastGlyph.advance;
97
+ const targetWidth = textWidthInTextSpace * effectiveScaleX * scale;
98
+ // Position
99
+ const x = transform.translateX * scale;
100
+ const ascent = scaledFontSize * 0.8;
101
+ const y = transform.translateY * scale - ascent;
102
+ // Calculate rotation angle from transform
103
+ const angle = Math.atan2(transform.skewY, transform.scaleX) * (180 / Math.PI);
104
+ // Position the span
105
+ span.style.left = `${x}px`;
106
+ span.style.top = `${y}px`;
107
+ span.style.fontSize = `${scaledFontSize}px`;
108
+ span.style.lineHeight = "1";
109
+ span.style.whiteSpace = "pre"; // Preserve spaces
110
+ span.style.height = `${spanHeight}px`; // Fill gap to next line
111
+ layer.appendChild(span);
112
+ pendingSpans.push({ span, targetWidth, angle });
113
+ }
114
+ // After all spans are in the DOM, measure and apply scaleX to match target widths
115
+ if (pendingSpans.length > 0) {
116
+ for (const { span, targetWidth, angle } of pendingSpans) {
117
+ const naturalWidth = span.offsetWidth;
118
+ if (naturalWidth > 0 && targetWidth > 0) {
119
+ const scaleX = targetWidth / naturalWidth;
120
+ const transforms = [];
121
+ if (Math.abs(scaleX - 1) > 0.001) {
122
+ transforms.push(`scaleX(${scaleX})`);
123
+ }
124
+ if (Math.abs(angle) > 0.1) {
125
+ transforms.push(`rotate(${angle}deg)`);
126
+ }
127
+ if (transforms.length > 0) {
128
+ span.style.transform = transforms.join(" ");
129
+ span.style.transformOrigin = "left top";
130
+ }
131
+ }
132
+ }
133
+ }
134
+ }
135
+ //# sourceMappingURL=render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../../../../../src/ui/viewer/text/render.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Text selection controller for the text layer.
3
+ *
4
+ * Works together with CSS (user-select: none on layer, user-select: text on spans)
5
+ * to prevent selection issues when mouse moves through gaps between text.
6
+ */
7
+ /**
8
+ * Attach selection handling to a text layer element.
9
+ * Returns a cleanup function to remove event listeners.
10
+ */
11
+ export declare function attachSelectionController(layer: HTMLDivElement): () => void;
12
+ //# sourceMappingURL=selection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selection.d.ts","sourceRoot":"","sources":["../../../../../src/ui/viewer/text/selection.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,IAAI,CA8D3E"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Text selection controller for the text layer.
3
+ *
4
+ * Works together with CSS (user-select: none on layer, user-select: text on spans)
5
+ * to prevent selection issues when mouse moves through gaps between text.
6
+ */
7
+ /**
8
+ * Attach selection handling to a text layer element.
9
+ * Returns a cleanup function to remove event listeners.
10
+ */
11
+ export function attachSelectionController(layer) {
12
+ let isSelecting = false;
13
+ let lastValidRange = null;
14
+ function handleMouseDown(e) {
15
+ if (e.button !== 0)
16
+ return;
17
+ isSelecting = true;
18
+ lastValidRange = null;
19
+ }
20
+ function handleMouseMove(e) {
21
+ if (!isSelecting || e.buttons !== 1) {
22
+ return;
23
+ }
24
+ const selection = document.getSelection();
25
+ if (!selection || selection.rangeCount === 0)
26
+ return;
27
+ // Check if we're over a text span
28
+ const target = document.elementFromPoint(e.clientX, e.clientY);
29
+ const isOverSpan = target?.classList.contains("udoc-text-span");
30
+ if (isOverSpan) {
31
+ // Save the current valid selection
32
+ try {
33
+ lastValidRange = selection.getRangeAt(0).cloneRange();
34
+ }
35
+ catch {
36
+ // Ignore errors
37
+ }
38
+ }
39
+ else if (lastValidRange) {
40
+ // In a gap - restore last valid selection to prevent collapse/reversal
41
+ try {
42
+ const currentRange = selection.getRangeAt(0);
43
+ // Only restore if the selection has collapsed or changed unexpectedly
44
+ if (selection.isCollapsed ||
45
+ (currentRange.toString().length < lastValidRange.toString().length * 0.5)) {
46
+ selection.removeAllRanges();
47
+ selection.addRange(lastValidRange.cloneRange());
48
+ }
49
+ }
50
+ catch {
51
+ // Ignore errors
52
+ }
53
+ }
54
+ }
55
+ function handleMouseUp() {
56
+ isSelecting = false;
57
+ lastValidRange = null;
58
+ }
59
+ // Attach listeners
60
+ layer.addEventListener("mousedown", handleMouseDown);
61
+ document.addEventListener("mousemove", handleMouseMove);
62
+ document.addEventListener("mouseup", handleMouseUp);
63
+ // Return cleanup function
64
+ return () => {
65
+ layer.removeEventListener("mousedown", handleMouseDown);
66
+ document.removeEventListener("mousemove", handleMouseMove);
67
+ document.removeEventListener("mouseup", handleMouseUp);
68
+ };
69
+ }
70
+ //# sourceMappingURL=selection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selection.js","sourceRoot":"","sources":["../../../../../src/ui/viewer/text/selection.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CAAC,KAAqB;IAC7D,IAAI,WAAW,GAAG,KAAK,CAAC;IACxB,IAAI,cAAc,GAAiB,IAAI,CAAC;IAExC,SAAS,eAAe,CAAC,CAAa;QACpC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAE3B,WAAW,GAAG,IAAI,CAAC;QACnB,cAAc,GAAG,IAAI,CAAC;IACxB,CAAC;IAED,SAAS,eAAe,CAAC,CAAa;QACpC,IAAI,CAAC,WAAW,IAAI,CAAC,CAAC,OAAO,KAAK,CAAC,EAAE,CAAC;YACpC,OAAO;QACT,CAAC;QAED,MAAM,SAAS,GAAG,QAAQ,CAAC,YAAY,EAAE,CAAC;QAC1C,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,UAAU,KAAK,CAAC;YAAE,OAAO;QAErD,kCAAkC;QAClC,MAAM,MAAM,GAAG,QAAQ,CAAC,gBAAgB,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;QAC/D,MAAM,UAAU,GAAG,MAAM,EAAE,SAAS,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;QAEhE,IAAI,UAAU,EAAE,CAAC;YACf,mCAAmC;YACnC,IAAI,CAAC;gBACH,cAAc,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC;YACxD,CAAC;YAAC,MAAM,CAAC;gBACP,gBAAgB;YAClB,CAAC;QACH,CAAC;aAAM,IAAI,cAAc,EAAE,CAAC;YAC1B,uEAAuE;YACvE,IAAI,CAAC;gBACH,MAAM,YAAY,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;gBAC7C,sEAAsE;gBACtE,IAAI,SAAS,CAAC,WAAW;oBACrB,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC,MAAM,GAAG,cAAc,CAAC,QAAQ,EAAE,CAAC,MAAM,GAAG,GAAG,CAAC,EAAE,CAAC;oBAC9E,SAAS,CAAC,eAAe,EAAE,CAAC;oBAC5B,SAAS,CAAC,QAAQ,CAAC,cAAc,CAAC,UAAU,EAAE,CAAC,CAAC;gBAClD,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,gBAAgB;YAClB,CAAC;QACH,CAAC;IACH,CAAC;IAED,SAAS,aAAa;QACpB,WAAW,GAAG,KAAK,CAAC;QACpB,cAAc,GAAG,IAAI,CAAC;IACxB,CAAC;IAED,mBAAmB;IACnB,KAAK,CAAC,gBAAgB,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;IACrD,QAAQ,CAAC,gBAAgB,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;IACxD,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;IAEpD,0BAA0B;IAC1B,OAAO,GAAG,EAAE;QACV,KAAK,CAAC,mBAAmB,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;QACxD,QAAQ,CAAC,mBAAmB,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;QAC3D,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;IACzD,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * TypeScript types for text selection.
3
+ *
4
+ * These types mirror the Rust JsTextRun/JsPositionedGlyph/JsTransform structures.
5
+ */
6
+ /** Positioned glyph with character mapping. */
7
+ export interface PositionedGlyph {
8
+ /** X position in text space. */
9
+ x: number;
10
+ /** Y position in text space. */
11
+ y: number;
12
+ /** Horizontal advance width. */
13
+ advance: number;
14
+ /** Unicode character for this glyph. */
15
+ char?: string;
16
+ }
17
+ /** Transform matrix. */
18
+ export interface TextTransform {
19
+ scaleX: number;
20
+ skewY: number;
21
+ skewX: number;
22
+ scaleY: number;
23
+ translateX: number;
24
+ translateY: number;
25
+ }
26
+ /** Text run containing positioned glyphs. */
27
+ export interface TextRun {
28
+ /** Unicode text for this run. */
29
+ text?: string;
30
+ /** Positioned glyphs with character mappings. */
31
+ glyphs: PositionedGlyph[];
32
+ /** Font size in points. */
33
+ fontSize: number;
34
+ /** Combined transform (frame transform * text transform). */
35
+ transform: TextTransform;
36
+ }
37
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/ui/viewer/text/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,+CAA+C;AAC/C,MAAM,WAAW,eAAe;IAC9B,gCAAgC;IAChC,CAAC,EAAE,MAAM,CAAC;IACV,gCAAgC;IAChC,CAAC,EAAE,MAAM,CAAC;IACV,gCAAgC;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,wCAAwC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAwB;AACxB,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,6CAA6C;AAC7C,MAAM,WAAW,OAAO;IACtB,iCAAiC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,2BAA2B;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,SAAS,EAAE,aAAa,CAAC;CAC1B"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * TypeScript types for text selection.
3
+ *
4
+ * These types mirror the Rust JsTextRun/JsPositionedGlyph/JsTransform structures.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../src/ui/viewer/text/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -112,6 +112,16 @@ export class UDoc {
112
112
  * More efficient than calling `page_info` for each page.
113
113
  */
114
114
  all_page_info(id: string): any;
115
+ /**
116
+ * Get text content for a specific page (for text selection).
117
+ *
118
+ * Returns an array of text runs, each containing:
119
+ * - `text`: Unicode text string
120
+ * - `glyphs`: Positioned glyphs with character mappings
121
+ * - `fontSize`: Font size in points
122
+ * - `transform`: Combined transform matrix
123
+ */
124
+ get_page_text(id: string, page_index: number): any;
115
125
  /**
116
126
  * Get current license status.
117
127
  */
@@ -280,6 +290,7 @@ export interface InitOutput {
280
290
  readonly udoc_get_limit: (a: number, b: number, c: number, d: bigint) => bigint;
281
291
  readonly udoc_get_outline: (a: number, b: number, c: number, d: number) => void;
282
292
  readonly udoc_get_page_annotations: (a: number, b: number, c: number, d: number, e: number) => void;
293
+ readonly udoc_get_page_text: (a: number, b: number, c: number, d: number, e: number) => void;
283
294
  readonly udoc_has_document: (a: number, b: number, c: number) => number;
284
295
  readonly udoc_has_feature: (a: number, b: number, c: number) => number;
285
296
  readonly udoc_license_status: (a: number, b: number) => void;