Parent
#328.
What to build
A Divider is the line you get by typing --- on an empty line. A selected Divider looks exactly like an unselected one, so the caret seems to vanish. This is common: Backspace on the empty line under a Divider selects the Divider with no mark. A second Backspace then deletes it with no warning.
After the fix, a selected Divider shows the house soft focus ring. The name "Divider" also joins the glossary.
Acceptance criteria
Blocked by
None — can start now.
Agent brief
Type: AFK — an agent can finish this alone.
Category: bug
Current behavior:
- The pad loads StarterKit's
horizontalRule node. StarterKit.configure in apps/webapp/src/components/TipTap/TipTap.tsx:107 does not turn it off. Only the chat composer does (apps/webapp/src/components/chatroom/components/MessageComposer/hooks/useTiptapEditor.ts:142).
- The Divider look is a 2px
base-300 top border with a 2rem margin. It is the hr rule inside the editor-prose-shared mixin (apps/webapp/src/styles/_prose-mirror-body.scss:102-106). That mixin is shared by the pad and chat. Chat has no Divider, so a rule there changes only the pad.
- ProseMirror adds the class
ProseMirror-selectednode to a selected leaf node (prosemirror-view 1.42.3 dist/index.js:1501).
- No stylesheet in
apps/webapp/src styles that class, and Tiptap core does not inject one. So a selected Divider shows nothing.
--- inserts the Divider above the current line and keeps the line (@tiptap/core src/inputRules/nodeInputRule.ts:68, insert at start - 1).
- Right after
---, the first Backspace undoes the input rule and gives back the --- text. Any caret move clears that undo (@tiptap/core src/InputRule.ts:251 and src/extensions/keymap.ts:16).
- After a caret move, Backspace on the empty line under a Divider deletes that line and selects the Divider. Unverified in a browser; the Verify steps check it.
Desired behavior:
- One rule on the Divider when it has that class:
outline: var(--focus-ring-soft); outline-offset: 2px.
- This copies
.history-author-block--current in apps/webapp/src/styles/editor/_history-authors.scss:15-18.
- Use the token, not a new color.
Where to start:
- Add the rule inside the
hr rule in apps/webapp/src/styles/_prose-mirror-body.scss, as &.ProseMirror-selectednode.
- Add a row to the table in
.cursor/docs/design-system.md §State language: "node selected (leaf block)". Recipe: outline: var(--focus-ring-soft); outline-offset: 2px on .ProseMirror-selectednode. First use: Divider.
- Add one line to
CONTEXT.md §Pad outline, after Subtitle: "Divider — the horizontalRule node in the pad. A light split inside a Section. It makes no TOC entry, heading chat or Section. Not the daisyUI divider class."
- The State language table is wide. Realign it with
bunx prettier --write .cursor/docs/design-system.md CONTEXT.md apps/webapp/src/styles/_prose-mirror-body.scss. Do not run bun run format:fix; it writes every unformatted file in the repo.
Line numbers are hints as of 2026-09-28; the agent searches by symbol.
Rules that apply:
.cursor/docs/design-system.md §State language: the soft ring is the one focus-ring token. The design-system skill (.cursor/skills/design-system/SKILL.md) points at the same file.
apps/webapp/CLAUDE.md §TipTap Styling: never add a .scss file beside an extension. Pad-only styles go under styles/editor/. This rule sits inside the shared hr rule, so the Divider look keeps one home.
CONTEXT.md is the glossary: one name per thing. Use "Divider" in code comments and docs.
AGENTS.md §Test Policy: add no test. This is a look change, checked in the browser.
Verify:
bun run check. It runs lint, lint:styles, the Prettier check, typecheck and the agent-docs check.
- Start the stack with
make dev-local. Open http://localhost:3000/editor on a desktop browser. Read the WEBAPP line of the make dev-local output for the real port.
- Test light and dark. In DevTools, set
data-theme="docsplus", then data-theme="docsplus-dark", on <html>.
- On an empty line, type
---. A Divider appears above the line.
- Press ArrowUp, then ArrowDown, so the caret is back on the empty line under the Divider. This clears the input-rule undo.
- Press Backspace. The empty line goes, and the Divider shows the soft ring.
- Click in a text line. The ring goes away.
- Click right on the Divider line. The ring shows again.
- Phone: a narrow window does not produce the mobile shell. Use a real phone, or a mobile user agent on a real pad route (
/<slug>). Repeat the Backspace step.
Out of scope
Parent
#328.
What to build
A Divider is the line you get by typing
---on an empty line. A selected Divider looks exactly like an unselected one, so the caret seems to vanish. This is common: Backspace on the empty line under a Divider selects the Divider with no mark. A second Backspace then deletes it with no warning.After the fix, a selected Divider shows the house soft focus ring. The name "Divider" also joins the glossary.
Acceptance criteria
outline: var(--focus-ring-soft)withoutline-offset: 2px.docsplus) and the dark theme (docsplus-dark)..cursor/docs/design-system.md§State language has a "node selected (leaf block)" row with this recipe.CONTEXT.md§Pad outline defines "Divider".bun run checkpasses.Blocked by
None — can start now.
Agent brief
Type: AFK — an agent can finish this alone.
Category: bug
Current behavior:
horizontalRulenode.StarterKit.configureinapps/webapp/src/components/TipTap/TipTap.tsx:107does not turn it off. Only the chat composer does (apps/webapp/src/components/chatroom/components/MessageComposer/hooks/useTiptapEditor.ts:142).base-300top border with a 2rem margin. It is thehrrule inside theeditor-prose-sharedmixin (apps/webapp/src/styles/_prose-mirror-body.scss:102-106). That mixin is shared by the pad and chat. Chat has no Divider, so a rule there changes only the pad.ProseMirror-selectednodeto a selected leaf node (prosemirror-view1.42.3dist/index.js:1501).apps/webapp/srcstyles that class, and Tiptap core does not inject one. So a selected Divider shows nothing.---inserts the Divider above the current line and keeps the line (@tiptap/coresrc/inputRules/nodeInputRule.ts:68, insert atstart - 1).---, the first Backspace undoes the input rule and gives back the---text. Any caret move clears that undo (@tiptap/coresrc/InputRule.ts:251andsrc/extensions/keymap.ts:16).Desired behavior:
outline: var(--focus-ring-soft); outline-offset: 2px..history-author-block--currentinapps/webapp/src/styles/editor/_history-authors.scss:15-18.Where to start:
hrrule inapps/webapp/src/styles/_prose-mirror-body.scss, as&.ProseMirror-selectednode..cursor/docs/design-system.md§State language: "node selected (leaf block)". Recipe:outline: var(--focus-ring-soft); outline-offset: 2pxon.ProseMirror-selectednode. First use: Divider.CONTEXT.md§Pad outline, after Subtitle: "Divider — thehorizontalRulenode in the pad. A light split inside a Section. It makes no TOC entry, heading chat or Section. Not the daisyUIdividerclass."bunx prettier --write .cursor/docs/design-system.md CONTEXT.md apps/webapp/src/styles/_prose-mirror-body.scss. Do not runbun run format:fix; it writes every unformatted file in the repo.Line numbers are hints as of 2026-09-28; the agent searches by symbol.
Rules that apply:
.cursor/docs/design-system.md§State language: the soft ring is the one focus-ring token. Thedesign-systemskill (.cursor/skills/design-system/SKILL.md) points at the same file.apps/webapp/CLAUDE.md§TipTap Styling: never add a.scssfile beside an extension. Pad-only styles go understyles/editor/. This rule sits inside the sharedhrrule, so the Divider look keeps one home.CONTEXT.mdis the glossary: one name per thing. Use "Divider" in code comments and docs.AGENTS.md§Test Policy: add no test. This is a look change, checked in the browser.Verify:
bun run check. It runs lint,lint:styles, the Prettier check, typecheck and the agent-docs check.make dev-local. Openhttp://localhost:3000/editoron a desktop browser. Read theWEBAPPline of themake dev-localoutput for the real port.data-theme="docsplus", thendata-theme="docsplus-dark", on<html>.---. A Divider appears above the line./<slug>). Repeat the Backspace step.Out of scope