- import `notionJsonToBlocks` in `Block.client.js` and prioritize `text/_notion-blocks-v3-production` mime over `text/html` on paste
- implement `notionJsonToBlocks` and `notionValueToBlock` in `clipboard.js` to convert notion block json to editor blocks, preserving native types (`to_do`, `sub_sub_header`, etc.)
- update README to document the notion mime priority in paste handling
- detect `to-do-list` (Notion) and `task-list` (GitHub MD) classes as checklist containers
- handle notion `<div class="checkbox-on/off">` as checkbox indicator in list items
- update README to document newly recognized HTML tags for checklist input
- add refs for submenu trigger and panel elements
- compute available space above/below using getBoundingClientRect
- dynamically set submenu side to avoid overflow outside viewport
- add RepeatIcon component to shared icons index
- import and display RepeatIcon in the transform menu item of BlockActionsMenu
- remove maxHeight constraint and overflow-y-auto from actions menu panel
- introduce `useDropdownPlacement` hook to compute above/below positioning based on available viewport space
- apply dynamic `maxHeight` and position class to `BlockInsertMenu` and `BlockActionsMenu` panels
- attach `triggerRef` to menu trigger buttons for accurate anchor rect calculation
- use `useLayoutEffect` to avoid layout flicker on open
- initialize position state with a `bottom` field set to null
- use `bottom` css property instead of `top` when menu flips above the anchor to prevent floating when content shrinks on query filtering
- remove `items.length` from layout effect dependencies since repositioning on item count change caused the flipping issue
- build `positionStyle` object conditionally based on whether `bottom` is set
- introduce `BlockInsertMenu` dropdown to insert a new block after the current one
- extract `TYPE_ICON_BOX_CLASS` constant shared between insert menu and transform menu
- align `BlockActionsMenu` transform list item padding/gap to match new insert menu style
- update README to document the new insert menu behaviour and enabled blocks filtering
- remove Headless UI Menu and Fragment imports, unused TextIcon import
- implement manual BlockActionsMenu component to avoid pointerdown-triggered open interfering with drag start
- open dropdown only on click after checking justDragged flag
- handle outside click and Escape key for closing
- migrate submenu hover logic from BlockMenuTransformItem into new component
- add `BlockMenuTransformItem` component with hover-triggered submenu panel
- import `ArrowRight01Icon` and `TextIcon` icons for transform UI
- track drag state via `justDraggedRef` to prevent menu opening after drag
- expose `close` from `<Menu>` render prop to allow manual close on transform select
- wire transform options from block registry into the new submenu item
- add context menu on drag handle with transform, duplicate and delete actions
- introduce `MenuOpenSync` helper to keep handle visible while menu is open
- pass `onTransformBlock`, `onDuplicateBlock`, `onDeleteBlock` and `enabledBlocks` props to Block
- compute `transformOptions` via `useMemo` filtering allowed text block types
- update BlockEditor to wire new block action handlers down to each Block
- update README to document new block action props and menu behavior
- add clipboard.js with htmlToBlocks, blocksToHtml, and blocksToPlainText helpers
- handle single-paragraph html paste as inline splice preserving block type
- handle multi-block html paste by splitting current block and merging head/tail paragraphs
- add onPasteInline and onPasteBlocks props to Block component
- implement handlePasteInline and handlePasteBlocks in BlockEditor
- fallback to plain text insertion when html is absent or yields no blocks
- update README to document clipboard behaviour and new paste handlers
- add `handleFocus` in Block to reopen slash menu on focus if content starts with `/`
- add `outerRef` on editor root div to detect outside clicks
- add `useEffect` with document `mousedown` listener to close slash menu when clicking outside the editor or on a different block
- add `data-slash-menu` attribute on SlashMenu to exclude it from the close trigger
- replace `getCaretOffset` with `countCharsUpTo` to treat `<br>` as 1 char
- rewrite `locateOffset` to walk dom tree and account for `<br>` nodes
- add `textLength` helper to compute model-consistent node length
- update `getCaretOffset` and `getCaretRange` to use new counting logic
- add `removeAllMarks` function to inline/types.js
- implement `applyRemoveAllMarks` handler in BlockEditor client
- add `TextClearIcon` button with separator in Toolbar component
- expose `onClearMarks` prop on InlineToolbar
- update README to document new clear formatting action
- remove unused `placeholder` prop from BlockEditor component
- add `block-editor--sole-empty` class when editor has a single empty block
- show placeholder via opacity transition instead of content injection
- always render `attr(data-placeholder)` content, toggle visibility with opacity
- add 150ms ease transition for smooth placeholder fade in/out
- show placeholder when block is focused, hovered, or editor is sole-empty
- add `onSelectBlock` prop to Block component wired to drag handle click
- implement `selectBlock` function in BlockEditor to select a single block and clear text selection
- update blockRegistry to accept ReactNode icons instead of emoji strings
- replace emoji icons in all built-in block types with icon components from shared icons
- add `isHexColor` and `collectUsedColors` helpers to inline/types.js
- extend `color` and `highlight` marks to accept hex color strings in addition to palette keys
- pass `usedColors` (collected from document) to InlineToolbar
- update InlineToolbar color popover to show used colors and a free color input
- add new icons to shared icons index
- update README to reflect icon, color, and toolbar popover changes
- move `e.preventDefault()` from toolbar container to each individual button to avoid broad focus prevention
- default `linkNewTab` state to `false` instead of `true` for new links
- add `onMouseDown` prevention to color grid buttons
- add `linkNewTab` state (default true) in InlineToolbar
- pass `newTab` flag through `onToggleMark` on link submit and remove
- restore `newTab` value when reopening the link popover
- add checkbox ui in link popover to toggle new tab behavior
- update link serialization to render `target="_blank" rel="noopener noreferrer"` when `newTab` is set
- add `newTab` field to link mark type definition
- add `toolbarPinnedRef` in BlockEditor to prevent toolbar from closing while a popover is focused
- pass `onPinChange` callback to InlineToolbar to toggle the pinned state
- notify parent via `onPinChange` whenever popover state changes
- remove rect-change effect that was incorrectly closing popovers on selection update
- migrate block content from plain strings to InlineNode[] structure
- add inline toolbar (bold, italic, code, color, link) on text selection
- add checklist block type with toggle support
- add image block type (URL-based, phase 2)
- add inline serialization helpers (inlineToDom, domToInline)
- add inline types and length utilities
- extend caret utils with range get/set support
- update block registry and all existing block types for new content model
- update demo blocks in ComponentsPage to use rich inline content
- update README to reflect new architecture
- swap PlusSignIcon for Add01Icon in Block.client.js add button
- remove PlusSignIcon export from shared icons index
- update README to reflect renamed icon
- replace `+` and `⋮⋮` text with `PlusSignIcon` and `DragDropVerticalIcon` components
- add `Add01Icon` export to shared icons index
- update README to reference icon names and link to icons source
- add `sameSet` helper to compare two Sets for equality
- add `dragRef` to track drag state (mode, startBlockId, origin coords)
- replace `selectionchange`-based detection with `mousemove`/`mouseup` listeners
- support `text` mode: stay native until cursor leaves origin block, then switch to `block` mode
- support `block` mode: extend selection across blocks as cursor moves between them
- support `marquee` mode: rect-based selection when mousedown starts outside a contentEditable
- use `sameSet` to avoid redundant `setSelectedBlockIds` calls on unchanged selections
- add `isSelected` prop and overlay highlight to Block component
- implement double ctrl+a: first selects block content, second selects all blocks
- add `onSelectAllBlocks` callback prop to Block
- add `selectedBlockIds` state and `selectAllBlocks`/`deleteSelectedBlocks` helpers in BlockEditor
- detect cross-block native selection via `selectionchange` and convert to block selection
- handle backspace/delete key to remove all selected blocks
- clear block selection on click outside or focus change
- update README to document multi-block selection behaviour
- export new icons used by the feature
- intercept Ctrl/Cmd+A to select only the current block's content, preventing cross-block merge bug
- increase slash menu width from 280 to 375 and max-height from 320 to 360
- enlarge icon container, increase gap and padding, and upsize text in slash menu items
- increase menu width and max height constants
- add SHORTCUT_HINT map displaying markdown shortcuts per block type
- update empty state and list container to use rounded-lg and shadow-md
- add section label header above block items
- show monospace shortcut hint on each menu item
- tighten item padding and icon size for denser layout
- move slash menu keyboard listener to document capture phase to prevent contentEditable default behaviors
- use circular navigation for arrow keys in slash menu
- separate undo/redo shortcuts into dedicated global keydown handler
- add adaptive positioning for slash menu with flip-up, horizontal clamp, and max-height constraints
- increase block vertical padding from py-0.5 to py-1.5 for better readability
- increase editor container vertical padding from py-3 to py-6
- show placeholder text only on hover or focus instead of always visible
- import TagInput component and useState hook
- define ROLE_OPTIONS with color metadata for demo purposes
- add TagInputDemo wrapper component to manage local state
- add PreviewBlock showcasing default, colored badge, and error variants
- add `dot` and `onRemove` props to Badge for colored dot and removable tag support
- delete RoleBadge component in favor of Badge with dot prop
- update UserCreateModal, UserEditModal, and UsersPage to use Badge instead of RoleBadge
- remove RoleBadge export from shared components index
- update `renderClientManifest` to export a `ZenModulesClient` React component instead of `export {}`
- update docs to explain why rendering the component is required under Next.js 15+/Turbopack and add usage example in `app/layout.js`
- document `.server.js` suffix requirement for node-only imports in DEV.md
- add client-safe subentries table and server-only barrel warnings in MODULES.md
- fix `crud.js` and `database/index.js` to import from `db.server.js`
- replace `createRequire` with `pathToFileURL` in `discover.server.js` for ESM-only modules
- update admin navigation and registry to use safe client-compatible imports
- bump version to 1.4.132
- update MODULES.md to document dual-entry pattern (main vs ./client) and explain why client entry must not import server-only code
- filter client manifest to only include modules exposing a `./client` subpath export
- add `moduleHasClientEntry` helper in discover.server.js to check package.json exports
- update cli.js to use `moduleHasClientEntry` when rendering the client manifest
- update init.js and modules/index.js to align with new client entry convention
- introduce `OUTPUT_CLIENT` constant and `renderClientManifest` for `'use client'` bundle
- rename `renderManifest` to `renderServerManifest` for clarity
- update `sync` command to write both server and client manifests
- update `findInstalledModuleNames` to support custom package path resolution
- rewrite MODULES.md to explain dual-manifest architecture and client hydration rationale
- replace dynamic import strategy with static manifest generated by `zen-modules sync` cli
- add `zen-modules` binary entry point in `package.json`
- add `cli.js` implementing the `zen-modules sync` command
- update `discover.server.js` to consume static manifest instead of scanning at runtime
- update `index.js` to reflect new module registration flow
- update `init.js` to accept pre-resolved modules from manifest
- revise docs to document manifest format, sync triggers, and build requirements
- replace top-level `import { cookies } from 'next/headers'` with lazy `await import('next/headers')` inside handler
- document the constraint in PROJECT.md: no top-level next/headers or next/navigation imports reachable from module register() chains
- remove `protectAdmin`/`isAdmin` re-exports from `features/admin/index.js` to avoid top-level `next/headers` import
- add `./features/admin/protect` export entry in `package.json`
- lazy-import `next/headers` in `router.js` `requireAuth` to defer resolution
- update `features/admin/README.md` to document new import paths
- translate `features/auth/index.js` comment to French for consistency
- update barrel comment to document why actions.js is excluded
- remove re-exports of server actions that depend on `next/headers` at module load time
- instruct consumers to import actions explicitly via @zen/core/features/auth/actions
- update comment to clarify that only manifest.permissions are registered before seed
- remove register() invocation from loadModules() to prevent incompatible next.js imports in cli context