From 9aa7620461a5a4aefa78e5c45ced14acf6e04439 Mon Sep 17 00:00:00 2001 From: agent_vscode Date: Sun, 12 Jul 2026 21:35:37 +0300 Subject: [PATCH] =?UTF-8?q?fix(client):=20=D0=BD=D0=BE=D0=BC=D0=B5=D1=80?= =?UTF-8?q?=20=D1=81=D0=BD=D0=BE=D1=81=D0=BA=D0=B8=20=D0=B2=D1=81=D1=82?= =?UTF-8?q?=D0=B0=D1=91=D1=82=20=D0=B8=D0=BD=D0=BB=D0=B0=D0=B9=D0=BD,=20?= =?UTF-8?q?=D0=B0=20=D0=BD=D0=B5=20=D0=BD=D0=B0=20=D0=BE=D1=82=D0=B4=D0=B5?= =?UTF-8?q?=D0=BB=D1=8C=D0=BD=D0=BE=D0=B9=20=D1=81=D1=82=D1=80=D0=BE=D0=BA?= =?UTF-8?q?=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Номер «N.» рисовался через .definitionContent > :first-child::before, но tiptap-react оборачивает содержимое NodeViewContent в дополнительный блочный div [data-node-view-content-react], поэтому :first-child — это обёртка, а не

. Инлайновый ::before на блочной обёртке с блочным

внутри падал на свою строку (регрессия «+1 строка» из #420). Селекторы переведены на .definitionContent p:first-child / p:last-child — номер и сброс полей теперь бьют по самому абзацу (контент определения — paragraph+, вложенных абзацев нет, так что попадание однозначно), работает и с обёрткой, и без неё. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../components/footnote/footnote.module.css | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/apps/client/src/features/editor/components/footnote/footnote.module.css b/apps/client/src/features/editor/components/footnote/footnote.module.css index 1ccc37ae..83c190ab 100644 --- a/apps/client/src/features/editor/components/footnote/footnote.module.css +++ b/apps/client/src/features/editor/components/footnote/footnote.module.css @@ -92,13 +92,23 @@ wrapper, never in the document model) and is rendered inline at the start of the first content line via ::before. This keeps text and wrapped lines flush to the left margin — no hanging indent — while the editable contentDOM stays - the FIRST DOM child (#146). */ + the FIRST DOM child (#146). + + The rules below target `p:first-child`, NOT `> :first-child`: tiptap-react + wraps the NodeViewContent children in an extra block-level div + (`[data-node-view-content-react]`, style="white-space: inherit"), so + `.definitionContent`'s first child is that wrapper, not the paragraph. An + inline ::before on the block wrapper (whose child is a block

) drops onto + its own line above the text — the "+1 line" regression. `p:first-child` + reaches the real first paragraph so the number stays inline, and it works + whether or not the wrapper is present (definition content is `paragraph+`, + so there are no nested paragraphs to mis-match). */ .definitionContent { flex: 1 1 auto; min-width: 0; } -.definitionContent > :first-child::before { +.definitionContent p:first-child::before { content: var(--footnote-number, "?") ". "; color: var(--mantine-color-dimmed); font-variant-numeric: tabular-nums; @@ -108,12 +118,13 @@ /* The inner editable paragraph inherits `.ProseMirror p { margin: 0.5em 0 }`. Drop the outer margins so the definition sits tight to the heading above and the ::before number aligns with the top of the row — same approach used for - callouts in core.css. */ -.definitionContent > :first-child { + callouts in core.css. Target the paragraphs directly (through the + tiptap-react content wrapper), same reasoning as the ::before rule above. */ +.definitionContent p:first-child { margin-top: 0; } -.definitionContent > :last-child { +.definitionContent p:last-child { margin-bottom: 0; }