@heycys/gallery 0.1.0 → 0.1.1

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 (237) hide show
  1. package/THIRD-PARTY-NOTICES.md +51 -1
  2. package/browser/editor/components/callout/index.mjs +40 -15
  3. package/browser/editor/components/columns/page.mjs +41 -28
  4. package/browser/editor/components/details/index.mjs +2 -1
  5. package/browser/editor/components/dialog/index.mjs +2 -1
  6. package/browser/editor/components/dialog/page.mjs +0 -18
  7. package/browser/editor/components/divider/index.mjs +1 -1
  8. package/browser/editor/components/figure/page.mjs +10 -1
  9. package/browser/editor/components/file/page.mjs +2 -2
  10. package/browser/editor/components/flowchart/add.mjs +2 -2
  11. package/browser/editor/components/heading/index.mjs +2 -0
  12. package/browser/editor/components/heading/page.mjs +6 -0
  13. package/browser/editor/components/highlight/index.mjs +4 -20
  14. package/browser/editor/components/icons.mjs +5 -2
  15. package/browser/editor/components/image/page.mjs +2 -2
  16. package/browser/editor/components/installed/index.mjs +71 -25
  17. package/browser/editor/components/installed/page.mjs +122 -21
  18. package/browser/editor/components/kit.mjs +3 -0
  19. package/browser/editor/components/media/page.mjs +44 -14
  20. package/browser/editor/components/pages.mjs +2 -2
  21. package/browser/editor/components/registry.mjs +56 -30
  22. package/browser/editor/components/section/index.mjs +2 -1
  23. package/browser/editor/components/set-apart.mjs +24 -0
  24. package/browser/editor/components/table/index.mjs +5 -3
  25. package/browser/editor/components/table/page.mjs +29 -18
  26. package/browser/editor/page/annotate/anchors.mjs +4 -3
  27. package/browser/editor/page/annotate/index.mjs +61 -34
  28. package/browser/editor/page/autosave.mjs +50 -4
  29. package/browser/editor/page/beside.mjs +5 -5
  30. package/browser/editor/page/block-menu/colors.mjs +3 -1
  31. package/browser/editor/page/block-menu/index.mjs +8 -6
  32. package/browser/editor/page/blocks.mjs +16 -7
  33. package/browser/editor/page/caret.mjs +4 -1
  34. package/browser/editor/page/changes/bar.mjs +102 -0
  35. package/browser/editor/page/changes/ghost.mjs +206 -0
  36. package/browser/editor/page/changes/gone-words.mjs +94 -0
  37. package/browser/editor/page/changes/index.mjs +447 -0
  38. package/browser/editor/page/changes/words.mjs +27 -0
  39. package/browser/editor/page/clipboard/import/colors.mjs +3 -3
  40. package/browser/editor/page/clipboard/index.mjs +32 -13
  41. package/browser/editor/page/clipboard/own/blocks.mjs +14 -5
  42. package/browser/editor/page/clipboard/own/describe.mjs +16 -7
  43. package/browser/editor/page/clipboard/own/export.mjs +6 -6
  44. package/browser/editor/page/clipboard/own/selection.mjs +2 -2
  45. package/browser/editor/page/clipboard/own/writers.mjs +0 -11
  46. package/browser/editor/page/columns/index.mjs +1 -1
  47. package/browser/editor/page/commit.mjs +19 -4
  48. package/browser/editor/page/conflicts.mjs +6 -26
  49. package/browser/editor/page/convert.mjs +8 -7
  50. package/browser/editor/page/core.mjs +55 -17
  51. package/browser/editor/page/drag/index.mjs +40 -24
  52. package/browser/editor/page/drag/preview.mjs +9 -4
  53. package/browser/editor/page/editor.mjs +70 -15
  54. package/browser/editor/page/emoji-picker/emoji-tab.mjs +22 -13
  55. package/browser/editor/page/emoji-picker/grid.mjs +7 -5
  56. package/browser/editor/page/emoji-picker/icon-tab.mjs +4 -4
  57. package/browser/editor/page/emoji-picker/icons.mjs +0 -1
  58. package/browser/editor/page/emoji-picker/index.mjs +11 -9
  59. package/browser/editor/page/emoji-picker/styles.mjs +161 -2
  60. package/browser/editor/page/emoji-picker/support.mjs +6 -4
  61. package/browser/editor/page/emoji-picker/upload.mjs +12 -11
  62. package/browser/editor/page/fills.mjs +5 -3
  63. package/browser/editor/page/fold/index.mjs +348 -0
  64. package/browser/editor/page/fold/rule.mjs +125 -0
  65. package/browser/editor/page/folded.mjs +23 -0
  66. package/browser/editor/page/format-bar/bar.mjs +2 -1
  67. package/browser/editor/page/format-bar/index.mjs +1 -1
  68. package/browser/editor/page/geometry.mjs +8 -6
  69. package/browser/editor/page/handle/index.mjs +17 -6
  70. package/browser/editor/page/hints/index.mjs +1 -1
  71. package/browser/editor/page/insert/index.mjs +30 -17
  72. package/browser/editor/page/long-runs.mjs +75 -0
  73. package/browser/editor/page/look.mjs +15 -3
  74. package/browser/editor/page/margin.mjs +45 -24
  75. package/browser/editor/page/menu.mjs +69 -25
  76. package/browser/editor/page/merge.mjs +24 -0
  77. package/browser/editor/page/notices.mjs +1 -1
  78. package/browser/editor/page/offered.mjs +1 -1
  79. package/browser/editor/page/outline/folds.mjs +11 -10
  80. package/browser/editor/page/outline/index.mjs +131 -45
  81. package/browser/editor/page/outline/list.mjs +23 -11
  82. package/browser/editor/page/outline/read.mjs +1 -1
  83. package/browser/editor/page/outline/strip.mjs +7 -1
  84. package/browser/editor/page/panel.mjs +5 -4
  85. package/browser/editor/page/resize/index.mjs +1 -1
  86. package/browser/editor/page/selection/delete.mjs +8 -6
  87. package/browser/editor/page/selection/index.mjs +10 -3
  88. package/browser/editor/page/session.mjs +54 -3
  89. package/browser/editor/page/table/cell-bar.mjs +4 -1
  90. package/browser/editor/page/table/cells.mjs +1 -1
  91. package/browser/editor/page/table/icons.mjs +1 -1
  92. package/browser/editor/page/table/index.mjs +13 -8
  93. package/browser/editor/page/table/widths.mjs +9 -4
  94. package/browser/editor/page/text-select/index.mjs +18 -3
  95. package/browser/editor/page/tooltip.mjs +1 -1
  96. package/browser/editor/page/type-grid.mjs +4 -3
  97. package/browser/editor/page/typing/code-edges.mjs +63 -17
  98. package/browser/editor/page/typing/index.mjs +12 -6
  99. package/browser/editor/page/typing/leave.mjs +1 -1
  100. package/browser/shared/annotations.mjs +8 -10
  101. package/browser/shared/code-folds.mjs +5 -1
  102. package/browser/shared/colors.mjs +15 -13
  103. package/browser/shared/component-catalog.mjs +24 -10
  104. package/browser/shared/components/callout.mjs +4 -2
  105. package/browser/shared/components/index.mjs +61 -7
  106. package/browser/shared/components/installed.mjs +75 -5
  107. package/browser/shared/components/page.mjs +10 -1
  108. package/browser/shared/components/table.mjs +1 -1
  109. package/browser/shared/components/text.mjs +2 -2
  110. package/browser/shared/document-look.mjs +178 -0
  111. package/browser/shared/emoji/data/LICENSE-lucide.txt +43 -0
  112. package/browser/shared/emoji/data/README.md +4 -2
  113. package/browser/shared/emoji/data/categories.json +1 -1
  114. package/browser/shared/emoji/data/keywords-en.json +1 -1
  115. package/browser/shared/emoji/data/keywords-zh.json +1 -1
  116. package/browser/shared/emoji/data/names.json +1 -1
  117. package/browser/shared/emoji/data/positions.json +1 -1
  118. package/browser/shared/emoji/data/twemoji-index.json +1 -1
  119. package/browser/shared/emoji/data/twemoji-svg.bin +0 -0
  120. package/browser/shared/emoji/data.mjs +10 -12
  121. package/browser/shared/emoji/emoji.mjs +8 -7
  122. package/browser/shared/emoji/icon-value.mjs +4 -3
  123. package/browser/shared/html-tree.mjs +11 -5
  124. package/browser/shared/i18n/en.mjs +67 -8
  125. package/browser/shared/long-runs.mjs +39 -0
  126. package/browser/shared/new-names.mjs +5 -2
  127. package/browser/shared/outline.mjs +194 -0
  128. package/browser/shared/preferences.mjs +10 -4
  129. package/browser/shared/session.mjs +5 -4
  130. package/browser/shared/workspace-look.mjs +91 -0
  131. package/browser/shared/zoom.mjs +5 -5
  132. package/dist/chunk-3HIRPVLU.mjs +2 -0
  133. package/dist/chunk-4FS7Z7WR.mjs +2 -0
  134. package/dist/{chunk-LHTFLRB6.mjs → chunk-5MHMDLZD.mjs} +2 -2
  135. package/dist/{chunk-YXAUQPVK.mjs → chunk-5ZKJ3H4P.mjs} +3 -3
  136. package/dist/{chunk-ZBIM6ARY.mjs → chunk-64K7IPLO.mjs} +55 -16
  137. package/dist/{chunk-QYKCJ7FG.mjs → chunk-6QXGZM36.mjs} +1 -1
  138. package/dist/chunk-6RGJOMJP.mjs +16 -0
  139. package/dist/{chunk-EUX7IC5J.mjs → chunk-7DTINW6U.mjs} +2 -2
  140. package/dist/{chunk-6CYG3Z4V.mjs → chunk-AJ73XJF3.mjs} +1 -1
  141. package/dist/chunk-AUZGSZJH.mjs +13 -0
  142. package/dist/{chunk-7QQBR7PB.mjs → chunk-BFE45AKL.mjs} +1 -1
  143. package/dist/chunk-BGGDRNYQ.mjs +10 -0
  144. package/dist/{chunk-L4DVONOG.mjs → chunk-BXO2ZY5P.mjs} +1 -1
  145. package/dist/chunk-CEH4MRCC.mjs +2 -0
  146. package/dist/chunk-CY2FNNAB.mjs +16 -0
  147. package/dist/{chunk-LC7YNQFG.mjs → chunk-DFUDV4LX.mjs} +1 -1
  148. package/dist/chunk-DKXG4XDG.mjs +2 -0
  149. package/dist/chunk-E7LWZRXY.mjs +4 -0
  150. package/dist/chunk-EZQ34M3F.mjs +124 -0
  151. package/dist/chunk-FDLXYYG4.mjs +4 -0
  152. package/dist/chunk-FUKQNOQS.mjs +9 -0
  153. package/dist/{chunk-DB4WKGYF.mjs → chunk-GB5SOYQJ.mjs} +2 -2
  154. package/dist/{chunk-ACOPDCNB.mjs → chunk-IVDLMMBD.mjs} +1 -1
  155. package/dist/chunk-JPOSLGOC.mjs +6 -0
  156. package/dist/chunk-JVHHHGEA.mjs +3 -0
  157. package/dist/chunk-L3QKH4OK.mjs +26 -0
  158. package/dist/{chunk-B3VTYBYR.mjs → chunk-LCTHTZIL.mjs} +2 -2
  159. package/dist/chunk-LEF6DRCK.mjs +59 -0
  160. package/dist/chunk-LS4F7JUM.mjs +2 -0
  161. package/dist/chunk-NO5NJCHO.mjs +2 -0
  162. package/dist/{chunk-UNUEWH4S.mjs → chunk-NQPVAU63.mjs} +1 -1
  163. package/dist/chunk-O35FIXRB.mjs +2 -0
  164. package/dist/chunk-PL6GHLGD.mjs +15 -0
  165. package/dist/{chunk-G7TOXONE.mjs → chunk-QJIR2BLP.mjs} +1 -1
  166. package/dist/chunk-QUPLVPB2.mjs +7 -0
  167. package/dist/chunk-R7BNENLY.mjs +4 -0
  168. package/dist/chunk-S6O4UHLC.mjs +2 -0
  169. package/dist/{chunk-HMHK3EQ6.mjs → chunk-SGJWQKEI.mjs} +1 -1
  170. package/dist/chunk-SYGN7GLU.mjs +2 -0
  171. package/dist/chunk-TYK6VNAB.mjs +10 -0
  172. package/dist/{chunk-EVJ3BX3M.mjs → chunk-U6KNPJPR.mjs} +1 -1
  173. package/dist/{chunk-YZ5Z6H4W.mjs → chunk-UALRNVSE.mjs} +1 -1
  174. package/dist/chunk-UMHUSOPJ.mjs +2 -0
  175. package/dist/chunk-V3HXVQEM.mjs +2 -0
  176. package/dist/{chunk-UXUK4PMC.mjs → chunk-V5JTW2LH.mjs} +1 -1
  177. package/dist/chunk-V5VXUJKG.mjs +2 -0
  178. package/dist/chunk-VBXMADMP.mjs +2 -0
  179. package/dist/chunk-VNV55RUA.mjs +2 -0
  180. package/dist/chunk-VPD2PS35.mjs +2 -0
  181. package/dist/chunk-W3BGBJQW.mjs +2 -0
  182. package/dist/chunk-W4VKN3GF.mjs +7 -0
  183. package/dist/chunk-W5BXXPDJ.mjs +3 -0
  184. package/dist/{chunk-Z52HTUW7.mjs → chunk-XNROSH2T.mjs} +2 -2
  185. package/dist/chunk-XUNHRCOG.mjs +6 -0
  186. package/dist/{chunk-6U2SLSDN.mjs → chunk-Y6RLRPG3.mjs} +1 -1
  187. package/dist/cli.mjs +1 -1
  188. package/dist/server.mjs +1 -1
  189. package/dist/worker.mjs +1 -1
  190. package/kit/math.js +18 -2
  191. package/kit/report.css +248 -137
  192. package/kit/runtime.js +126 -51
  193. package/kit/tables.js +51 -1
  194. package/kit/ui.js +97 -0
  195. package/package.json +1 -1
  196. package/release.json +8 -8
  197. package/sdk/doc-kit.d.ts +9 -3
  198. package/skill/SKILL.md +22 -10
  199. package/skill/references/building-components.md +46 -6
  200. package/skill/references/example-report.html +1 -1
  201. package/skill/references/writing-html.md +4 -4
  202. package/skill/sdk/doc-kit.d.ts +9 -3
  203. package/web/assets/index-Bh74DfsV.css +1 -0
  204. package/web/assets/index-UW0RyFFt.js +13 -0
  205. package/web/index.html +2 -2
  206. package/browser/editor/components/callout/page.mjs +0 -13
  207. package/dist/chunk-2PBALTR3.mjs +0 -57
  208. package/dist/chunk-3LA3EMDE.mjs +0 -15
  209. package/dist/chunk-5FRMCDPY.mjs +0 -16
  210. package/dist/chunk-5LEK2CBS.mjs +0 -2
  211. package/dist/chunk-5OFN5AHC.mjs +0 -2
  212. package/dist/chunk-5SIYS5HN.mjs +0 -2
  213. package/dist/chunk-5TEK3RAD.mjs +0 -2
  214. package/dist/chunk-7GHT2UCA.mjs +0 -15
  215. package/dist/chunk-ATCJYAR4.mjs +0 -2
  216. package/dist/chunk-C7HWOBIF.mjs +0 -2
  217. package/dist/chunk-E7VYDG2X.mjs +0 -2
  218. package/dist/chunk-FQGQH4KM.mjs +0 -2
  219. package/dist/chunk-GPF4YWWB.mjs +0 -9
  220. package/dist/chunk-GYQV7Y4J.mjs +0 -120
  221. package/dist/chunk-HQQMJCQJ.mjs +0 -10
  222. package/dist/chunk-IERUOGC3.mjs +0 -6
  223. package/dist/chunk-ITNLYXXV.mjs +0 -3
  224. package/dist/chunk-NFIBI4IP.mjs +0 -26
  225. package/dist/chunk-O52JMOCZ.mjs +0 -2
  226. package/dist/chunk-QMQUXTU4.mjs +0 -12
  227. package/dist/chunk-QVWVFC5K.mjs +0 -6
  228. package/dist/chunk-QZY6Q64C.mjs +0 -2
  229. package/dist/chunk-TDQP3DKQ.mjs +0 -10
  230. package/dist/chunk-V4CPWKMZ.mjs +0 -2
  231. package/dist/chunk-VACRB2NE.mjs +0 -3
  232. package/dist/chunk-W63L7367.mjs +0 -7
  233. package/dist/chunk-W7CXPCRV.mjs +0 -6
  234. package/dist/chunk-XINNG4F2.mjs +0 -4
  235. package/dist/chunk-YL2DPWVS.mjs +0 -4
  236. package/web/assets/index-B6Ai3wsa.js +0 -13
  237. package/web/assets/index-SYPC3EZy.css +0 -1
package/kit/report.css CHANGED
@@ -6,7 +6,9 @@
6
6
  download, their ascent and descent rewritten so a line's ink sits in the middle of its line box, as
7
7
  Feishu's first Windows font (Tahoma) has it; Segoe UI's own leaves room above its letters, and the
8
8
  Chinese text, on the same baseline, sat a pixel low in a selected block's fill and a colored one's
9
- background. Absent elsewhere (macOS, Linux): the stack goes on to the next family. */
9
+ background. PingFang SC stands before it in --doc-font: where the system has PingFang SC (macOS,
10
+ iOS, a Windows it was installed on) the whole text is set in it and this alias is not reached.
11
+ Where Segoe UI is absent (macOS, Linux) the stack goes on to the next family. */
10
12
  @font-face { font-family: "Doc Segoe"; src: local("Segoe UI"), local("SegoeUI"); font-weight: 400; ascent-override: 100%; descent-override: 25%; line-gap-override: 0%; }
11
13
  @font-face { font-family: "Doc Segoe"; src: local("Segoe UI Italic"), local("SegoeUI-Italic"); font-weight: 400; font-style: italic; ascent-override: 100%; descent-override: 25%; line-gap-override: 0%; }
12
14
  @font-face { font-family: "Doc Segoe"; src: local("Segoe UI Semibold"), local("SegoeUI-Semibold"); font-weight: 600; ascent-override: 100%; descent-override: 25%; line-gap-override: 0%; }
@@ -16,15 +18,19 @@
16
18
 
17
19
  :root {
18
20
  color-scheme: light dark;
19
- --doc-bg: light-dark(#fcfcfc, #181818);
21
+ /* The page: #2c2c2b on white in light (Notion's), its own pair in dark; the lines below are the text at a strength. */
22
+ --doc-bg: light-dark(#ffffff, #181818);
20
23
  --doc-surface: light-dark(#ffffff, #202020);
21
- --doc-text: light-dark(#1d1d1f, #f3f3f3);
24
+ --doc-text: light-dark(#2c2c2b, #f3f3f3); /* the text: Notion's (and DingTalk's) #2c2c2b, the editor's own --ge-tx */
22
25
  --doc-muted: light-dark(#6e6e73, #a1a1a6);
23
- --doc-border: light-dark(rgb(29 29 31 / 12%), rgb(243 243 243 / 13%));
24
- --doc-grid: light-dark(rgb(29 29 31 / 8%), rgb(243 243 243 / 8%));
26
+ --doc-border: light-dark(rgb(44 44 43 / 12%), rgb(243 243 243 / 13%));
27
+ --doc-grid: light-dark(rgb(44 44 43 / 8%), rgb(243 243 243 / 8%));
25
28
  --doc-accent: light-dark(#2678d8, #72adf0);
26
29
  --doc-accent-soft: light-dark(#eaf3fd, #172a3d);
27
- --doc-list-marker: light-dark(rgb(20 86 240), rgb(76 136 255)); /* list numbers and bullets: Feishu's blue */
30
+ /* List numbers and bullets: a blue of their own (the user's #2e7cd1 of 2026-11-07, a purer blue than the palette's
31
+ #387dc9 that links take; in dark the same hue at the dark palette's lightness, where the palette's #5e87c9 leans
32
+ gray), quieter than Feishu's, whose place and shapes they keep. */
33
+ --doc-list-marker: light-dark(#2e7cd1, #5492d4);
28
34
  --doc-success: var(--doc-series-3);
29
35
  --doc-warning: var(--doc-series-2);
30
36
  /* Cursor Canvas category red; the other Gallery series colors stay unchanged. */
@@ -37,13 +43,20 @@
37
43
  --doc-series-4: light-dark(#927ab8, #b4a0d2);
38
44
  --doc-series-5: light-dark(#c04848, #fc6b83);
39
45
  --doc-series-6: light-dark(#65bdba, #89d1ce);
40
- /* System UI fonts: Apple's, then Segoe UI with its line on its glyphs on Windows (Doc Segoe,
41
- above), then Chinese ones. */
42
- --doc-font: ui-sans-serif, -apple-system, BlinkMacSystemFont, "Doc Segoe", "Segoe UI Variable Text", "Segoe UI", "Helvetica Neue", "PingFang SC", "Microsoft YaHei", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
46
+ /* PingFang SC first (the user's feedback of 2026-11-06, notes/建议1.txt): where the system has it
47
+ (macOS, iOS) the whole text, Chinese, Latin and figures, is set in it, whatever the page's lang;
48
+ elsewhere the system's UI fonts as before: Apple's, then Segoe UI with its line on its glyphs on
49
+ Windows (Doc Segoe, above), then Microsoft YaHei for Chinese. */
50
+ --doc-font: "PingFang SC", ui-sans-serif, -apple-system, BlinkMacSystemFont, "Doc Segoe", "Segoe UI Variable Text", "Segoe UI", "Helvetica Neue", "Microsoft YaHei", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
43
51
  --doc-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, "PT Mono", "Liberation Mono", monospace;
44
- /* Links in the text: the muted gray in every block, on a thin line of Notion's gray always shown. */
45
- --doc-link: var(--doc-muted);
46
- --doc-link-line: light-dark(rgb(55 53 47 / 40%), rgb(255 255 255 / 28.2%));
52
+ /* Links in the text: the palette's blue (colors.mjs, .doc-text-blue: the format bar's 蓝色) in every block, with
53
+ no line but under the pointer, a thin one of the same blue there (the user's of 2026-11-07, Feishu's way). A link
54
+ shown with its icon and a page block (mention.css) keep Notion's look: the muted gray on a thin line of Notion's
55
+ gray always shown. */
56
+ --doc-link: light-dark(#387dc9, #5e87c9);
57
+ --doc-link-line: currentColor;
58
+ --doc-mention: var(--doc-muted);
59
+ --doc-mention-line: light-dark(rgb(55 53 47 / 40%), rgb(255 255 255 / 28.2%));
47
60
  /* Inline code (as Notion): red text on a faint fill. */
48
61
  --doc-code-inline: light-dark(#cf5148, #e8776d);
49
62
  --doc-code-inline-fill: var(--doc-hover);
@@ -52,12 +65,16 @@
52
65
  --doc-compact-figure-max-width: 520px;
53
66
  --doc-page-gutter: 20px;
54
67
  --doc-wide-gutter: clamp(12px, 2.5vw, 40px);
55
- /* A detail card (dialog.css): the room on each side of its text, how far it stays from the
56
- window's sides (a reader's card goes up to them), the room above and below it, where a press
57
- closes it, and its scrollbar's width. */
58
- --doc-dialog-side: 40px;
59
- --doc-dialog-edge: 0px;
60
- --doc-dialog-block-gutter: 40px;
68
+ /* A detail card (dialog.css), a little smaller than the workbench's settings dialogs (写作偏好's
69
+ 880 by 86% of the window, at most 900): its width, its height (80% of the window, at most 760px;
70
+ the window is the page's own, or in a workbench the workbench's, whose height the editor's
71
+ session gives as --doc-dialog-window-height: src/editor/page/session.mjs), the least room between
72
+ it and the window's sides, where a press closes it, the least room on each side of its text (the
73
+ reading column, centred where the card is wider), and its scrollbar's width. */
74
+ --doc-dialog-width: 760px;
75
+ --doc-dialog-height: min(calc(0.8 * var(--doc-dialog-window-height, 100dvh)), 760px);
76
+ --doc-dialog-margin: 24px;
77
+ --doc-dialog-pad: 48px;
61
78
  --doc-dialog-scrollbar: 10px;
62
79
  /* The gap above and below a block, one name per distinct gap (docs/render.md says which block
63
80
  takes which). A component (a card, a table, a callout, a row of columns, a widget) and a divider
@@ -118,8 +135,8 @@
118
135
  --doc-flow-line: light-dark(rgb(55 53 47 / 38%), rgb(255 255 255 / 34%));
119
136
  --doc-flow-badge: light-dark(rgb(55 53 47 / 8%), rgb(255 255 255 / 10%));
120
137
  /* The thin scrollbars the kit draws over a table's frame (tables.js). */
121
- --doc-scrollbar-thumb: light-dark(rgb(29 29 31 / 24%), rgb(243 243 243 / 26%));
122
- --doc-scrollbar-thumb-active: light-dark(rgb(29 29 31 / 42%), rgb(243 243 243 / 44%));
138
+ --doc-scrollbar-thumb: light-dark(rgb(44 44 43 / 24%), rgb(243 243 243 / 26%));
139
+ --doc-scrollbar-thumb-active: light-dark(rgb(44 44 43 / 42%), rgb(243 243 243 / 44%));
123
140
  /* Code blocks in Notion's look (its panel, monospace, toolbar and Prism colors), independent of
124
141
  chart categories. The room above and below the words of a code block's title and a disclosure's
125
142
  (their header row: code.css, details.css), one design for the two. */
@@ -163,6 +180,33 @@
163
180
  :root[data-doc-theme="light"] { color-scheme: light; }
164
181
  :root[data-doc-theme="dark"] { color-scheme: dark; }
165
182
 
183
+ /* The document's look (字体与布局: its doc.json's look, which the render puts on <html> as
184
+ data-doc-font, data-doc-size, data-doc-spacing and data-doc-measure; src/shared/document-look.mjs),
185
+ written here by kit-build.mjs from the values above (src/render/look-css.mjs): a rule of those
186
+ attributes giving the tokens their values for the serif or the mixed font (--doc-font the serif,
187
+ --doc-sans-font what it was; --doc-heading-font the serif), a size, a spacing and a width, in pixels,
188
+ and --doc-space, the factor the gaps are taken at, for a margin a stylesheet writes
189
+ in pixels of its own (calc(26px * var(--doc-space, 1)): a heading's, the title's). With none of
190
+ them, as a document without a look is, nothing here applies. */
191
+ :root[data-doc-font="serif"] { --doc-sans-font: "PingFang SC", ui-sans-serif, -apple-system, BlinkMacSystemFont, "Doc Segoe", "Segoe UI Variable Text", "Segoe UI", "Helvetica Neue", "Microsoft YaHei", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; --doc-font: "Iowan Old Style", "Palatino Linotype", Palatino, "Book Antiqua", Georgia, "Songti SC", "Noto Serif SC", "Noto Serif CJK SC", "Source Han Serif SC", SimSun, serif; }
192
+ :root[data-doc-font="mixed"] { --doc-heading-font: "Iowan Old Style", "Palatino Linotype", Palatino, "Book Antiqua", Georgia, "Songti SC", "Noto Serif SC", "Noto Serif CJK SC", "Source Han Serif SC", SimSun, serif; }
193
+ :root[data-doc-size="small"] { --doc-body-font-size: 15px; --doc-body-line-height: 24px; --doc-small-font-size: 12px; --doc-small-line-height: 17px; --doc-note-font-size: 13px; --doc-note-line-height: 19px; --doc-title-font-size: 26px; --doc-title-line-height: 34px; --doc-h1-font-size: 24px; --doc-h1-line-height: 33px; --doc-h2-font-size: 21px; --doc-h2-line-height: 29px; --doc-h3-font-size: 19px; --doc-h3-line-height: 27px; --doc-h4-font-size: 15px; --doc-h4-line-height: 23px; --doc-card-title-font-size: 17px; --doc-card-title-line-height: 24px; --doc-table-font-size: 14px; --doc-table-line-height: 19px; }
194
+ :root[data-doc-size="large"] { --doc-body-font-size: 18px; --doc-body-line-height: 29px; --doc-small-font-size: 15px; --doc-small-line-height: 21px; --doc-note-font-size: 16px; --doc-note-line-height: 23px; --doc-title-font-size: 32px; --doc-title-line-height: 41px; --doc-h1-font-size: 29px; --doc-h1-line-height: 40px; --doc-h2-font-size: 25px; --doc-h2-line-height: 35px; --doc-h3-font-size: 23px; --doc-h3-line-height: 32px; --doc-h4-font-size: 18px; --doc-h4-line-height: 27px; --doc-card-title-font-size: 20px; --doc-card-title-line-height: 28px; --doc-table-font-size: 17px; --doc-table-line-height: 23px; }
195
+ :root[data-doc-spacing="compact"] { --doc-body-line-height: 24px; --doc-small-line-height: 17px; --doc-note-line-height: 19px; --doc-title-line-height: 34px; --doc-h1-line-height: 34px; --doc-h2-line-height: 29px; --doc-h3-line-height: 26px; --doc-h4-line-height: 22px; --doc-card-title-line-height: 24px; --doc-table-line-height: 19px; --doc-component-gap: 15px; --doc-block-gap: 12px; --doc-media-gap: 11px; --doc-paragraph-gap: 9px; --doc-group-gap: 6px; --doc-list-gap: 4px; --doc-space: 0.75; }
196
+ :root[data-doc-spacing="loose"] { --doc-body-line-height: 28px; --doc-small-line-height: 19px; --doc-note-line-height: 21px; --doc-title-line-height: 38px; --doc-h1-line-height: 38px; --doc-h2-line-height: 33px; --doc-h3-line-height: 30px; --doc-h4-line-height: 26px; --doc-card-title-line-height: 26px; --doc-table-line-height: 21px; --doc-component-gap: 25px; --doc-block-gap: 20px; --doc-media-gap: 18px; --doc-paragraph-gap: 15px; --doc-group-gap: 10px; --doc-list-gap: 6px; --doc-space: 1.25; }
197
+ :root[data-doc-measure="narrow"] { --doc-content-max-width: 648px; }
198
+ :root[data-doc-measure="wide"] { --doc-content-max-width: 776px; }
199
+ :root[data-doc-size="small"][data-doc-spacing="compact"] { --doc-body-line-height: 23px; --doc-small-line-height: 16px; --doc-note-line-height: 18px; --doc-title-line-height: 32px; --doc-h1-line-height: 32px; --doc-h2-line-height: 28px; --doc-h3-line-height: 25px; --doc-h4-line-height: 21px; --doc-card-title-line-height: 22px; --doc-table-line-height: 18px; }
200
+ :root[data-doc-size="small"][data-doc-spacing="loose"] { --doc-body-line-height: 26px; --doc-small-line-height: 18px; --doc-note-line-height: 20px; --doc-title-line-height: 35px; --doc-h1-line-height: 35px; --doc-h2-line-height: 31px; --doc-h3-line-height: 28px; --doc-h4-line-height: 24px; --doc-card-title-line-height: 25px; --doc-table-line-height: 20px; }
201
+ :root[data-doc-size="large"][data-doc-spacing="compact"] { --doc-body-line-height: 27px; --doc-small-line-height: 20px; --doc-note-line-height: 21px; --doc-title-line-height: 39px; --doc-h1-line-height: 38px; --doc-h2-line-height: 33px; --doc-h3-line-height: 30px; --doc-h4-line-height: 25px; --doc-card-title-line-height: 26px; --doc-table-line-height: 22px; }
202
+ :root[data-doc-size="large"][data-doc-spacing="loose"] { --doc-body-line-height: 32px; --doc-small-line-height: 22px; --doc-note-line-height: 24px; --doc-title-line-height: 43px; --doc-h1-line-height: 43px; --doc-h2-line-height: 37px; --doc-h3-line-height: 34px; --doc-h4-line-height: 29px; --doc-card-title-line-height: 29px; --doc-table-line-height: 24px; }
203
+ /* 衬线体: the kit's own controls (the display menu, a code block's language, a diff's counts) keep the
204
+ sans, --doc-font itself given it back on them, for what in them names --doc-font again (the display
205
+ menu's card, controls.css) takes it there. 混合体: the title and every heading in the serif, of no
206
+ weight (:where), so a document's own rule for its headings wins as the text's font they inherit does not. */
207
+ :root[data-doc-font="serif"] :is(.doc-display, .doc-code-language, .doc-diff-stats) { --doc-font: var(--doc-sans-font); font-family: var(--doc-font); }
208
+ :where(:root[data-doc-font="mixed"] :is(.doc-title, h1, h2, h3, h4)) { font-family: var(--doc-heading-font); }
209
+
166
210
  /* The kit's words a stylesheet shows (--doc-word-<key>: an empty code block's title), written here
167
211
  from its table (src/render/kit/words.js, STYLE_WORDS) by kit-build.mjs: Chinese, and English where
168
212
  Gallery says its UI is (data-ge-language="en") or, in a file of its own, the page's lang is en. */
@@ -170,7 +214,7 @@
170
214
  :root[data-ge-language="en"], :root:not([data-ge-language])[lang|="en" i] { --doc-word-code-title: "Code"; }
171
215
 
172
216
  @media (max-width: 640px) {
173
- :root { --doc-page-gutter: 12px; }
217
+ :root { --doc-page-gutter: 12px; --doc-dialog-margin: 12px; --doc-dialog-pad: 16px; }
174
218
  }
175
219
 
176
220
  /* The document itself: the body's type and colors, holding the first paint until the page is
@@ -215,8 +259,11 @@ body {
215
259
 
216
260
  button, input, select, textarea { font: inherit; }
217
261
 
218
- /* A link is gray with a thin line under it, clear of Chinese characters, under the pointer as anywhere. */
219
- a { color: var(--doc-link); text-decoration: underline .05em var(--doc-link-line); text-underline-offset: .2em; }
262
+ /* A link is the palette's blue with no line under it, a thin one (1px, clear of Chinese characters) only while the
263
+ pointer is on it. The pointer's rule weighs what `a` weighs, so a link of a look of its own (a bookmark, a file,
264
+ a detail card's, one shown with its icon: their classes) never takes the line from it. */
265
+ a { color: var(--doc-link); text-decoration: none; text-underline-offset: .2em; }
266
+ a:where(:hover) { text-decoration: underline 1px var(--doc-link-line); }
220
267
  /* Underlined text: the line clear of Chinese characters, in inline code's red. */
221
268
  u { text-decoration: underline 2px var(--doc-code-inline); text-underline-offset: .3em; text-decoration-skip-ink: none; }
222
269
  /* An underline's line in another color than the red, or thinner or heavier than its 2px (the page
@@ -249,17 +296,27 @@ code:where(:not(:is(.doc-code > pre, .doc-diff-body) code)) {
249
296
  (runtime/spacing.js holds it in this span as the page renders). */
250
297
  .doc-range { white-space: nowrap; }
251
298
 
299
+ /* A long run (a path, a URL, a long identifier: more than 20 characters with no place to break inside
300
+ it, src/shared/long-runs.mjs) breaks where its line ends, an ordinary word staying whole:
301
+ runtime/spacing.js holds it in this span as the page renders (the page editor marks a block
302
+ holding one: editor/page/long-runs.mjs). Punctuation keeps its rules (no line starts with ,。)). */
303
+ .doc-long-run { word-break: break-all; }
304
+
252
305
  /* Inline text colors and highlights (<span class="doc-text-red">): Notion's nine colors
253
306
  (its text and background colors, light and dark). The page editor's selection toolbar writes
254
307
  these classes; both follow the light/dark theme. A text color is also --doc-ink, for a
255
308
  component that takes it over (a code block's plain text, a list item's marker, a formula block).
256
309
  A background is --doc-fill, and its deep shade --doc-fill-deep (its color's text color),
257
- for a line a component draws along its fill (a callout's). */
310
+ for a line a component draws along its fill (a callout's). Words in a line (a span: the format
311
+ bar's 背景颜色, an Agent's <mark>) take --doc-mark instead, a step deeper than a block's fill and
312
+ square: Notion keeps its inline colors apart from its block colors, Feishu's highlight on words
313
+ is deeper than its block backgrounds, and the user found the words' fill too faint (2026-11-06). */
258
314
  /* The fill a color class sets is its host's own, not passed down to what stands in it: a table's cell
259
315
  takes its own fill or the table's (table.css), never that of the panel or disclosure around it;
260
316
  a callout without a color its own default's, never the line of the panel it stands in. */
261
317
  @property --doc-fill { syntax: "*"; inherits: false; }
262
318
  @property --doc-fill-deep { syntax: "*"; inherits: false; }
319
+ @property --doc-mark { syntax: "*"; inherits: false; }
263
320
  .doc-text-gray { --doc-ink: var(--doc-muted); color: var(--doc-ink); }
264
321
  .doc-text-brown { --doc-ink: light-dark(#9f765a, #ba856f); color: var(--doc-ink); }
265
322
  .doc-text-orange { --doc-ink: light-dark(#d27b2d, #c77d48); color: var(--doc-ink); }
@@ -270,19 +327,20 @@ code:where(:not(:is(.doc-code > pre, .doc-diff-body) code)) {
270
327
  .doc-text-pink { --doc-ink: light-dark(#c14c8a, #d15796); color: var(--doc-ink); }
271
328
  .doc-text-red { --doc-ink: light-dark(#cf5148, #df5452); color: var(--doc-ink); }
272
329
  /* What every host of a color class has: the fill, as its background. Its corners are its host's own, one declaration
273
- each (a span here, a paragraph and heading below, a list item in flow.css, a card or a disclosure in its own
274
- stylesheet); a block that takes no corners is square, and says nothing. */
330
+ each (a paragraph and heading below, a list item in flow.css, a card or a disclosure in its own
331
+ stylesheet); a span and a block that takes no corners are square, and say nothing. */
275
332
  :is(.doc-highlight-gray, .doc-highlight-brown, .doc-highlight-orange, .doc-highlight-yellow, .doc-highlight-green, .doc-highlight-blue, .doc-highlight-purple, .doc-highlight-pink, .doc-highlight-red) { background: var(--doc-fill); -webkit-box-decoration-break: clone; box-decoration-break: clone; }
276
- span:is(.doc-highlight-gray, .doc-highlight-brown, .doc-highlight-orange, .doc-highlight-yellow, .doc-highlight-green, .doc-highlight-blue, .doc-highlight-purple, .doc-highlight-pink, .doc-highlight-red) { border-radius: 3px; }
277
- .doc-highlight-gray { --doc-fill: light-dark(#f0efed, #383836); --doc-fill-deep: var(--doc-muted); }
278
- .doc-highlight-brown { --doc-fill: light-dark(#f5ede9, #45362d); --doc-fill-deep: light-dark(#9f765a, #ba856f); }
279
- .doc-highlight-orange { --doc-fill: light-dark(#fbebde, #53361f); --doc-fill-deep: light-dark(#d27b2d, #c77d48); }
280
- .doc-highlight-yellow { --doc-fill: light-dark(#f9f3dc, #504425); --doc-fill-deep: light-dark(#cb9434, #ca9849); }
281
- .doc-highlight-green { --doc-fill: light-dark(#e8f1ec, #263d30); --doc-fill-deep: light-dark(#50946e, #529e72); }
282
- .doc-highlight-blue { --doc-fill: light-dark(#e5f2fc, #233850); --doc-fill-deep: light-dark(#387dc9, #5e87c9); }
283
- .doc-highlight-purple { --doc-fill: light-dark(#f3ebf9, #3c2d47); --doc-fill-deep: light-dark(#9a6bb4, #9d68d3); }
284
- .doc-highlight-pink { --doc-fill: light-dark(#fae9f1, #4e2b3c); --doc-fill-deep: light-dark(#c14c8a, #d15796); }
285
- .doc-highlight-red { --doc-fill: light-dark(#fce9e7, #502c29); --doc-fill-deep: light-dark(#cf5148, #df5452); }
333
+ /* Words in a line take the words' fill, deeper than a block's (Notion's inline colors are their own). */
334
+ span:is(.doc-highlight-gray, .doc-highlight-brown, .doc-highlight-orange, .doc-highlight-yellow, .doc-highlight-green, .doc-highlight-blue, .doc-highlight-purple, .doc-highlight-pink, .doc-highlight-red) { background: var(--doc-mark); }
335
+ .doc-highlight-gray { --doc-fill: light-dark(#f0efed, #383836); --doc-fill-deep: var(--doc-muted); --doc-mark: light-dark(#e0dfdd, #454542); }
336
+ .doc-highlight-brown { --doc-fill: light-dark(#f5ede9, #45362d); --doc-fill-deep: light-dark(#9f765a, #ba856f); --doc-mark: light-dark(#efdbce, #534034); }
337
+ .doc-highlight-orange { --doc-fill: light-dark(#fbebde, #53361f); --doc-fill-deep: light-dark(#d27b2d, #c77d48); --doc-mark: light-dark(#fbddc5, #654025); }
338
+ .doc-highlight-yellow { --doc-fill: light-dark(#f9f3dc, #504425); --doc-fill-deep: light-dark(#cb9434, #ca9849); --doc-mark: light-dark(#f8eab6, #614f26); }
339
+ .doc-highlight-green { --doc-fill: light-dark(#e8f1ec, #263d30); --doc-fill-deep: light-dark(#50946e, #529e72); --doc-mark: light-dark(#cfead9, #2c4b3a); }
340
+ .doc-highlight-blue { --doc-fill: light-dark(#e5f2fc, #233850); --doc-fill-deep: light-dark(#387dc9, #5e87c9); --doc-mark: light-dark(#cde5fb, #294564); }
341
+ .doc-highlight-purple { --doc-fill: light-dark(#f3ebf9, #3c2d47); --doc-fill-deep: light-dark(#9a6bb4, #9d68d3); --doc-mark: light-dark(#ebdaf6, #4b3859); }
342
+ .doc-highlight-pink { --doc-fill: light-dark(#fae9f1, #4e2b3c); --doc-fill-deep: light-dark(#c14c8a, #d15796); --doc-mark: light-dark(#f8d7e6, #5d3548); }
343
+ .doc-highlight-red { --doc-fill: light-dark(#fce9e7, #502c29); --doc-fill-deep: light-dark(#cf5148, #df5452); --doc-mark: light-dark(#fed7d1, #663632); }
286
344
 
287
345
  /* A block's color (颜色 in the page editor's block menu, Notion's block colors): the same classes on
288
346
  a paragraph or heading color its whole text, or put a background behind the whole block. The
@@ -326,7 +384,11 @@ span:is(.doc-highlight-gray, .doc-highlight-brown, .doc-highlight-orange, .doc-h
326
384
  /* A run with no place to break (a long path or URL in prose, a callout or inline code) breaks
327
385
  where it would leave its line, as a cell's, a caption's and a code block's already do: unbroken,
328
386
  it widened the page past a 360px window. break-word, not anywhere: a word still counts whole
329
- for min-content, so a table's columns and a card's least width stay as they were. */
387
+ for min-content. The page's words are whole at a line's end (word-break: normal), in a Chinese
388
+ page as in an English one; a long run (more than 20 characters with no place to break inside it,
389
+ src/shared/long-runs.mjs) breaks where its line ends instead of going whole to the next one: the
390
+ kit holds it in a span that breaks anywhere (.doc-long-run, base.css; runtime/spacing.js), the
391
+ page editor marks a block holding one (page/long-runs.mjs). */
330
392
  overflow-wrap: break-word;
331
393
  }
332
394
 
@@ -376,7 +438,7 @@ span:is(.doc-highlight-gray, .doc-highlight-brown, .doc-highlight-orange, .doc-h
376
438
  /* The title keeps one gap below it, whatever comes next, in the header or after it (a line under it,
377
439
  body text, a card, a section): its margin collapses with the next block's, through the header. */
378
440
  .doc-title {
379
- margin: 0 0 32px;
441
+ margin: 0 0 calc(32px * var(--doc-space, 1));
380
442
  font-size: var(--doc-title-font-size);
381
443
  font-weight: 600;
382
444
  line-height: var(--doc-title-line-height);
@@ -833,10 +895,12 @@ span:is(.doc-highlight-gray, .doc-highlight-brown, .doc-highlight-orange, .doc-h
833
895
  .doc-math-block:is(.doc-highlight-gray, .doc-highlight-brown, .doc-highlight-orange, .doc-highlight-yellow, .doc-highlight-green, .doc-highlight-blue, .doc-highlight-purple, .doc-highlight-pink, .doc-highlight-red) { padding-inline: 12px; border-radius: 10px; }
834
896
  .doc-math-block:is(.doc-text-gray, .doc-text-brown, .doc-text-orange, .doc-text-yellow, .doc-text-green, .doc-text-blue, .doc-text-purple, .doc-text-pink, .doc-text-red) { color: var(--doc-ink); }
835
897
 
836
- /* A link shown as its page's icon and title (图标视图, 页面块: shared/components/mention.mjs): the
837
- link's color and line as any link's (base.css), the icon before the title, a little taller than
838
- a capital and on the text's middle, rounded a little, the line under the title alone; an empty
839
- icon is a globe drawn in the link's color. */
898
+ /* A link shown as its page's icon and title (图标视图, 页面块: shared/components/mention.mjs): Notion's
899
+ look, not a text link's blue (base.css): the muted gray on a thin line always shown, under the pointer
900
+ too (--doc-mention, --doc-mention-line), the icon before the title, a little taller than a capital
901
+ and on the text's middle, rounded a little, the line under the title alone; an empty icon is a
902
+ globe drawn in the link's color. */
903
+ .doc-link-mention { color: var(--doc-mention); text-decoration: underline .05em var(--doc-mention-line); text-underline-offset: .2em; }
840
904
  .doc-link-mention-icon {
841
905
  display: inline-block;
842
906
  width: 1.125em;
@@ -855,10 +919,10 @@ span.doc-link-mention-icon {
855
919
  }
856
920
 
857
921
  /* A page block: the address is a document's. An empty icon is a page, as a page with none has in the
858
- workbench's tree, and the pointer lights it up as Notion's page mention, a whole to click on. */
922
+ workbench's tree (Lucide's file-text), and the pointer lights it up as Notion's page mention, a whole to click on. */
859
923
  .doc-link-mention[href]:not([href^="http" i]) > span.doc-link-mention-icon {
860
- -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5.75 2.75h5.5l3.5 3.5v9.5a1.5 1.5 0 0 1-1.5 1.5h-7.5a1.5 1.5 0 0 1-1.5-1.5V4.25a1.5 1.5 0 0 1 1.5-1.5z'/%3E%3Cpath d='M11 2.75v3c0 .41.34.75.75.75h3'/%3E%3Cpath d='M7.25 10h5.5M7.25 13h3.5'/%3E%3C/svg%3E");
861
- mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5.75 2.75h5.5l3.5 3.5v9.5a1.5 1.5 0 0 1-1.5 1.5h-7.5a1.5 1.5 0 0 1-1.5-1.5V4.25a1.5 1.5 0 0 1 1.5-1.5z'/%3E%3Cpath d='M11 2.75v3c0 .41.34.75.75.75h3'/%3E%3Cpath d='M7.25 10h5.5M7.25 13h3.5'/%3E%3C/svg%3E");
924
+ -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z'/%3E%3Cpath d='M14 2v5a1 1 0 0 0 1 1h5'/%3E%3Cpath d='M10 9H8M16 13H8M16 17H8'/%3E%3C/svg%3E");
925
+ mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z'/%3E%3Cpath d='M14 2v5a1 1 0 0 0 1 1h5'/%3E%3Cpath d='M10 9H8M16 13H8M16 17H8'/%3E%3C/svg%3E");
862
926
  }
863
927
  .doc-link-mention[href]:not([href^="http" i]):hover {
864
928
  border-radius: 1px;
@@ -965,6 +1029,9 @@ span.doc-link-mention-icon {
965
1029
  }
966
1030
  .doc-code-range::before { content: "·"; margin: 0 6px; }
967
1031
 
1032
+ /* The toolbar shows only while the pointer is over the block or the focus is in it (notion-lite's
1033
+ code actions), folded or not; a diff's counts always (what changed, not a control: its copy shows
1034
+ under the pointer, below). */
968
1035
  .doc-code-tools {
969
1036
  grid-area: 1 / 5;
970
1037
  display: flex;
@@ -975,7 +1042,6 @@ span.doc-link-mention-icon {
975
1042
  }
976
1043
  :is(.doc-code, .doc-diff):hover > .doc-code-tools,
977
1044
  .doc-code-tools:focus-within,
978
- .doc-code--folded > .doc-code-tools,
979
1045
  .doc-diff > .doc-code-tools { opacity: 1; pointer-events: auto; }
980
1046
  .doc-code-toolbar {
981
1047
  display: flex;
@@ -1013,8 +1079,8 @@ span.doc-link-mention-icon {
1013
1079
  :is(.doc-code-copy, .doc-code-wrap) svg { display: block; width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.3; stroke-linecap: round; stroke-linejoin: round; }
1014
1080
  :is(.doc-code-copy, .doc-code-wrap):hover { background: var(--doc-hover); }
1015
1081
 
1016
- /* Folded, its language and copy show at the right all the time, alone, with no bar (Feishu's; its
1017
- language is not picked then). */
1082
+ /* Folded, its toolbar is its language and copy alone, with no bar (Feishu's look; its language is
1083
+ not picked then), shown under the pointer as an open block's. */
1018
1084
  .doc-code--folded .doc-code-toolbar { background: none; box-shadow: none; }
1019
1085
  .doc-code--folded :is(.doc-code-separator, .doc-code-wrap) { display: none; }
1020
1086
 
@@ -1140,13 +1206,12 @@ span.doc-link-mention-icon {
1140
1206
 
1141
1207
  /* A narrow screen (the kit's narrowest breakpoint): a code block shows its code whole, its lines
1142
1208
  wrapped (a frame height of its own, a size, still holds: sizes.css), its title wraps rather than
1143
- being cut, and its toolbar lies over the header's right end when it shows (the pointer or the focus
1144
- in the block), taking no room from the title; a folded block's too. */
1209
+ being cut, and its toolbar lies over the header's right end when it shows (the pointer over the
1210
+ block or the focus in it), taking no room from the title. */
1145
1211
  @media (max-width: 420px) {
1146
1212
  .doc-code > pre { max-height: var(--doc-code-height, none); }
1147
1213
  .doc-code-title { white-space: normal; overflow-wrap: anywhere; text-overflow: clip; }
1148
1214
  .doc-code > .doc-code-tools { position: absolute; top: 4px; right: 0; }
1149
- .doc-code--folded:not(:hover) > .doc-code-tools:not(:focus-within) { opacity: 0; pointer-events: none; }
1150
1215
  }
1151
1216
 
1152
1217
  /* A code block's color (颜色 in the page editor's block menu, base.css's classes): its background, or
@@ -1199,24 +1264,26 @@ span.doc-link-mention-icon {
1199
1264
  /* Its text keeps the flow's gaps (flow.css), and a text, code or formula block at its edges takes none (these rules
1200
1265
  weigh as much as a component's own margin and stand before the components' files, which win): a
1201
1266
  card, a table, a callout or a disclosure first or last in it keeps its own margins, a panel's
1202
- inside being the one place a component is spaced as it is among text. A column's, a disclosure's
1203
- and a detail card's edges take none whatever the block (flow.css). */
1204
- :is(.doc-summary, .doc-panel) > :where(:first-child, .doc-icon + *) { margin-top: 0; }
1205
- :is(.doc-summary, .doc-panel) > :where(:last-child) { margin-bottom: 0; }
1267
+ inside being the one place a component is spaced as it is among text. A callout's blocks are
1268
+ spaced as a panel's, by the same rules (callout.css: one kind of block, its own look). A column's,
1269
+ a disclosure's and a detail card's edges take none whatever the block (flow.css). */
1270
+ :is(.doc-summary, .doc-panel, .doc-callout) > :where(:first-child, .doc-icon + *) { margin-top: 0; }
1271
+ :is(.doc-summary, .doc-panel, .doc-callout) > :where(:last-child) { margin-bottom: 0; }
1206
1272
 
1207
1273
  /* ---------- body text in flows ----------
1208
1274
  A flow is the page itself, a Sheet panel, the content of a section, the opening
1209
- summary, a highlight panel, a disclosure, a dialog or a column, and of a plain <div> (no class) grouping
1210
- blocks inside any of them but the page and a panel. The text blocks of a flow (its own
1275
+ summary, a highlight panel, a callout, a disclosure, a dialog, a column or a slot of an instance of a component
1276
+ package (data-doc-slot), and of a plain <div> (no class) grouping blocks inside any of them but the
1277
+ page and a panel. The text blocks of a flow (its own
1211
1278
  paragraphs, headings, lists, quotes and rules) read the same wherever they sit, and the rules
1212
- stop at them: the inside of a card, table, callout or report widget keeps its own styles, so a
1279
+ stop at them: the inside of a card, table or report widget keeps its own styles, so a
1213
1280
  component looks the same in any flow too. The flows are the components' descriptions' (flow,
1214
1281
  and the parts edited as flow: src/shared/components/): the one list of them is the selector
1215
1282
  below, which every rule of the flow nests in (&), and a unit test holds it to the descriptions.
1216
1283
  The rules have no weight (:where, and & has none of its own), so any component or report class
1217
1284
  wins. */
1218
1285
 
1219
- :where(.doc-page, .doc-section, .doc-summary, .doc-panel, .doc-details-content, .doc-dialog-content, [data-doc-sheet], .doc-column, :is(.doc-section, .doc-summary, .doc-panel, .doc-details-content, .doc-dialog-content, .doc-column) > div:not([class])) {
1286
+ :where(.doc-page, .doc-section, .doc-summary, .doc-panel, .doc-callout, .doc-details-content, .doc-dialog-content, [data-doc-sheet], .doc-column, [data-doc-slot], :is(.doc-section, .doc-summary, .doc-panel, .doc-callout, .doc-details-content, .doc-dialog-content, .doc-column, [data-doc-slot]) > div:not([class])) {
1220
1287
  & > :where(p),
1221
1288
  & > :where(ul, ol, blockquote) :where(p) {
1222
1289
  margin: 0 0 var(--doc-paragraph-gap);
@@ -1231,30 +1298,30 @@ span.doc-link-mention-icon {
1231
1298
  }
1232
1299
  & > :where(h1),
1233
1300
  & > :where(ul, ol) :where(li) > :where(h1) {
1234
- margin: 26px 0 10px;
1301
+ margin: calc(26px * var(--doc-space, 1)) 0 calc(10px * var(--doc-space, 1));
1235
1302
  font-size: var(--doc-h1-font-size);
1236
1303
  line-height: var(--doc-h1-line-height);
1237
1304
  }
1238
1305
  & > :where(h2),
1239
1306
  & > :where(ul, ol) :where(li) > :where(h2) {
1240
- margin: 22px 0 8px;
1307
+ margin: calc(22px * var(--doc-space, 1)) 0 calc(8px * var(--doc-space, 1));
1241
1308
  font-size: var(--doc-h2-font-size);
1242
1309
  line-height: var(--doc-h2-line-height);
1243
1310
  }
1244
1311
  & > :where(h3),
1245
1312
  & > :where(ul, ol) :where(li) > :where(h3) {
1246
- margin: 20px 0 8px;
1313
+ margin: calc(20px * var(--doc-space, 1)) 0 calc(8px * var(--doc-space, 1));
1247
1314
  font-size: var(--doc-h3-font-size);
1248
1315
  line-height: var(--doc-h3-line-height);
1249
1316
  }
1250
1317
  & > :where(h4),
1251
1318
  & > :where(ul, ol) :where(li) > :where(h4) {
1252
- margin: 16px 0 8px;
1319
+ margin: calc(16px * var(--doc-space, 1)) 0 calc(8px * var(--doc-space, 1));
1253
1320
  font-size: var(--doc-h4-font-size);
1254
1321
  line-height: var(--doc-h4-line-height);
1255
1322
  }
1256
1323
  & > :where(ul, ol) {
1257
- margin: 10px 0 var(--doc-block-gap);
1324
+ margin: calc(10px * var(--doc-space, 1)) 0 var(--doc-block-gap);
1258
1325
  padding-inline-start: 1.625em;
1259
1326
  }
1260
1327
  /* One gap between any two items, as Notion's and Feishu's: between items of a level, from an item
@@ -1276,7 +1343,7 @@ span.doc-link-mention-icon {
1276
1343
  & > :where(ul:not([class]), ol:not([class])), & :where(ol.doc-flow > li) > :where(ul:not([class]), ol:not([class])) {
1277
1344
  &, & :where(li > :is(ul, ol)) { list-style: none; }
1278
1345
  & :where(li) { position: relative; }
1279
- /* Lists (Feishu's): their markers the kit's, blue, left of the text: numbers 1., a., i. by depth,
1346
+ /* Lists (Feishu's place and shapes): their markers the kit's, in their own blue (--doc-list-marker), left of the text: numbers 1., a., i. by depth,
1280
1347
  each list from its start (or an item's value), right-aligned 6px from the text; bullets a dot, a
1281
1348
  ring, a square by depth, 16px left of the text, on the middle of the first line. A list with a
1282
1349
  class of its own keeps the browser's markers. */
@@ -1349,8 +1416,8 @@ span.doc-link-mention-icon {
1349
1416
  the tabs' margin). */
1350
1417
  :is(.doc-column, .doc-details-content, .doc-dialog-content) > :first-child { margin-top: 0; }
1351
1418
  :is(.doc-column, .doc-details-content, .doc-dialog-content, [data-doc-sheet]) > :last-child { margin-bottom: 0; }
1352
- /* A text block the reader left empty (a line of space, as in Notion) is one line high: a callout's
1353
- text and a disclosure's title too. */
1419
+ /* A text block the reader left empty (a line of space, as in Notion) is one line high: a disclosure's
1420
+ title too, and a callout the file has empty (an empty one of the editor's before 2026-11-07). */
1354
1421
  .doc-page :where(p, h1, h2, h3, h4, li, .doc-callout, .doc-details-summary-label):empty::after { content: "\200b"; }
1355
1422
 
1356
1423
  /* An item's color (颜色 in the page editor's block menu, notion-lite's: base.css's classes): a text
@@ -2052,20 +2119,19 @@ figure:is(.doc-image, .doc-file, .doc-bookmark, .doc-embed):not(:has(> *)) { dis
2052
2119
  :root.doc-dialog-open.doc-dialog-gutter { scrollbar-gutter: stable; }
2053
2120
  }
2054
2121
 
2055
- /* The reading column and 40px on each side of it, up to the page's sides (their edge while the page
2056
- is edited, dialog/): 100% is the window less a scrollbar's room kept, as it is for the page. Height
2057
- follows the content; long content stops at the viewport gutters and scrolls inside. A modal
2058
- dialog is fixed with inset 0, so `auto` would stretch it; `fit-content` matches the UA default. */
2122
+ /* The card is the workbench's settings dialogs' (组件列表, 写作偏好, Notion's centred dialog), a
2123
+ little smaller: 760 wide and 80% of the window high (at most 760), at least 24px clear of the
2124
+ window's sides (12px on a phone), whatever it holds, centred (a modal dialog is fixed with inset 0
2125
+ and margin auto); what it holds scrolls inside it. 100% is the window less a scrollbar's room kept,
2126
+ as it is for the page. The same while the page is edited. No header, no line, no close button.
2127
+ Their radius and their shadow (the workbench's --shaOutLg, light and dark). */
2059
2128
  .doc-dialog {
2060
- width: min(
2061
- calc(var(--doc-content-max-width) + (2 * var(--doc-dialog-side))),
2062
- calc(100% - (2 * var(--doc-dialog-edge)))
2063
- );
2064
- height: fit-content;
2129
+ width: min(var(--doc-dialog-width), calc(100% - (2 * var(--doc-dialog-margin))));
2130
+ height: min(var(--doc-dialog-height), calc(100dvh - (2 * var(--doc-dialog-margin))));
2065
2131
  min-width: 0;
2066
2132
  max-width: none;
2067
2133
  min-height: 0;
2068
- max-height: calc(100dvh - (2 * var(--doc-dialog-block-gutter)));
2134
+ max-height: none;
2069
2135
  margin: auto;
2070
2136
  padding: 0;
2071
2137
  overflow: hidden;
@@ -2073,26 +2139,53 @@ figure:is(.doc-image, .doc-file, .doc-bookmark, .doc-embed):not(:has(> *)) { dis
2073
2139
  border-radius: 12px;
2074
2140
  color: var(--doc-text);
2075
2141
  background: var(--doc-surface);
2076
- box-shadow: 0 0 0 1px var(--doc-border), 0 6px 14px rgb(15 15 15 / 8%), 0 18px 48px rgb(15 15 15 / 18%);
2142
+ box-shadow: 0 20px 24px rgb(25 25 25 / 5%), 0 5px 8px rgb(25 25 25 / 2.7%), 0 0 0 1px rgb(42 28 0 / 7%);
2077
2143
  }
2144
+ :root[data-doc-theme="dark"] .doc-dialog { box-shadow: 0 0 0 1px #383836, 0 14px 28px -6px rgb(25 25 25 / 20%), 0 2px 4px -1px rgb(25 25 25 / 11.8%); }
2078
2145
 
2079
- /* It comes up from a little below, the backdrop fading in. */
2146
+ @media (prefers-color-scheme: dark) {
2147
+ :root:not([data-doc-theme="light"]) .doc-dialog { box-shadow: 0 0 0 1px #383836, 0 14px 28px -6px rgb(25 25 25 / 20%), 0 2px 4px -1px rgb(25 25 25 / 11.8%); }
2148
+ }
2149
+
2150
+ /* Its middle is the middle of the window it stands in. In a workbench the page is a frame right of
2151
+ the sidebar and under the top bar, and the workbench's window is the one (the workbench covers its
2152
+ own bars, the frame's backdrop the rest: features/report/cards.ts); the editor's session gives
2153
+ where that window's middle falls in the page's (--doc-dialog-centre-x and -y, from the frame's
2154
+ place: src/editor/page/session.mjs), and the card goes that far from the frame's middle, as far as
2155
+ the frame lets it stay 24px clear of the frame's sides (never cut off): where the frame is too
2156
+ narrow or low for that, it stands nearer the frame's middle, in it where the frame has no more room
2157
+ than the card needs. Moved by its insets, a box as wide as the frame, never by a transform, which
2158
+ would make the card the containing block of the editor's fixed tools in it. Unsaid (a page on its
2159
+ own, an export), its middle is the page's window's. */
2160
+ .doc-dialog:modal {
2161
+ --doc-dialog-shift-x: clamp(-1 * var(--doc-dialog-room-x), calc(var(--doc-dialog-centre-x, 50%) - 50%), var(--doc-dialog-room-x));
2162
+ --doc-dialog-shift-y: clamp(-1 * var(--doc-dialog-room-y), calc(var(--doc-dialog-centre-y, 50%) - 50%), var(--doc-dialog-room-y));
2163
+ --doc-dialog-room-x: max(0px, calc((100% - min(var(--doc-dialog-width), calc(100% - (2 * var(--doc-dialog-margin))))) / 2 - var(--doc-dialog-margin)));
2164
+ --doc-dialog-room-y: max(0px, calc((100% - min(var(--doc-dialog-height), calc(100% - (2 * var(--doc-dialog-margin))))) / 2 - var(--doc-dialog-margin)));
2165
+ inset: var(--doc-dialog-shift-y) calc(-1 * var(--doc-dialog-shift-x)) calc(-1 * var(--doc-dialog-shift-y)) var(--doc-dialog-shift-x);
2166
+ }
2167
+
2168
+ /* It comes up as the settings dialogs do (their pop-in: 2px from above, 0.12s), the backdrop, their
2169
+ overlay's color (light 60%, dark 80%; the workbench's underlay outside a frame is the same, its
2170
+ --overlay), fading in where their overlay comes at once: the workbench's underlay hears of a card
2171
+ from the page a frame or two after it opens, and the fade, which it has too, hides that. Plain
2172
+ colors: a ::backdrop inherits from nothing in some browsers. */
2080
2173
  .doc-dialog[open] {
2081
2174
  display: flex;
2082
2175
  flex-direction: column;
2083
- animation: doc-dialog-in 0.16s cubic-bezier(0.2, 0.8, 0.2, 1);
2176
+ animation: doc-dialog-in 0.12s ease-out;
2084
2177
  }
2085
2178
 
2086
- .doc-dialog::backdrop { background: rgb(15 15 15 / 36%); }
2179
+ .doc-dialog::backdrop { background: rgb(15 15 15 / 60%); }
2087
2180
  .doc-dialog[open]::backdrop { animation: doc-dialog-fade 0.16s ease-out; }
2088
- :root[data-doc-theme="dark"] .doc-dialog::backdrop { background: rgb(0 0 0 / 55%); }
2181
+ :root[data-doc-theme="dark"] .doc-dialog::backdrop { background: rgb(15 15 15 / 80%); }
2089
2182
 
2090
2183
  @media (prefers-color-scheme: dark) {
2091
- :root:not([data-doc-theme="light"]) .doc-dialog::backdrop { background: rgb(0 0 0 / 55%); }
2184
+ :root:not([data-doc-theme="light"]) .doc-dialog::backdrop { background: rgb(15 15 15 / 80%); }
2092
2185
  }
2093
2186
 
2094
2187
  @keyframes doc-dialog-in {
2095
- from { opacity: 0; transform: translateY(8px) scale(0.985); }
2188
+ from { opacity: 0; transform: translateY(-2px); }
2096
2189
  }
2097
2190
 
2098
2191
  @keyframes doc-dialog-fade {
@@ -2112,22 +2205,17 @@ figure:is(.doc-image, .doc-file, .doc-bookmark, .doc-embed):not(:has(> *)) { dis
2112
2205
  flex-direction: column;
2113
2206
  }
2114
2207
 
2115
- /* Its text is the page's at any window: the reading column, and on a window narrower than the card
2116
- as far from the window's side as the page's text (--doc-dialog-inset: the page's gutter, less
2117
- what stands between the card and that side). Room for what it holds from the start (a card just
2118
- made holds a heading and an empty line), no more than the card may be high. What is scrolled into view keeps the content's padding
2119
- clear of the card's edges (scroll-padding, which the browser's caret following and
2120
- scrollIntoView both keep): the caret in the last block, or a block made at the end, takes the
2208
+ /* Its text is the reading column, centred, at most 712px and at least --doc-dialog-pad (48px; 16px
2209
+ on a phone) from the card's sides (--doc-dialog-inset). What is scrolled into view keeps the
2210
+ content's padding clear of the card's edges (scroll-padding, which the browser's caret following
2211
+ and scrollIntoView both keep): the caret in the last block, or a block made at the end, takes the
2121
2212
  content to its very end, the padding under it shown, where the browser stopped with that block
2122
2213
  against the card's bottom edge. 8px more below than the padding: the caret's box is its glyphs',
2123
2214
  a few pixels short of its line (the scroll stops at the end all the same). */
2124
2215
  .doc-dialog-content {
2125
- --doc-dialog-inset: max(
2126
- calc(var(--doc-page-gutter) - var(--doc-dialog-edge)),
2127
- calc((100% - var(--doc-content-max-width)) / 2)
2128
- );
2216
+ --doc-dialog-inset: max(var(--doc-dialog-pad), calc((100% - var(--doc-content-max-width)) / 2));
2129
2217
  min-width: 0;
2130
- min-height: min(160px, calc(100dvh - (2 * var(--doc-dialog-block-gutter))));
2218
+ min-height: 0;
2131
2219
  max-width: 100%;
2132
2220
  flex: 1 1 auto;
2133
2221
  padding: 32px var(--doc-dialog-inset) 40px;
@@ -2284,8 +2372,8 @@ figure:is(.doc-image, .doc-file, .doc-bookmark, .doc-embed):not(:has(> *)) { dis
2284
2372
  scroll height are sizes (sizes.css). A table is lines on the page (Notion's and Feishu's): the
2285
2373
  frame's rounded line around it and one line between every two rows and every two columns, all
2286
2374
  one color (--doc-hairline); no fills of its own. A header cell (th) looks as any other: its
2287
- gray and its bold are looks it was given (the page editor's 标题行 and 标题列 give them), it only
2288
- sticks. The frame and the table are one: the table fills the frame to its edge, the frame's
2375
+ gray and its bold are looks it was given (the page editor's 标题行 gives them; its 标题列 none:
2376
+ a header column only sticks), it only sticks. The frame and the table are one: the table fills the frame to its edge, the frame's
2289
2377
  line drawn over it. The line is drawn once wherever it lies: in dark it is a light veil over what
2290
2378
  is under it (tokens.css), so that it shows on a gray header cell and beside a gray highlight
2291
2379
  block as on the page, and a line drawn over another would be lighter there. In a block with a
@@ -2429,6 +2517,10 @@ figure:is(.doc-image, .doc-file, .doc-bookmark, .doc-embed):not(:has(> *)) { dis
2429
2517
  /* Keys moving into a frame that scrolls: the accent's line in place of its own. */
2430
2518
  .doc-table-wrap:focus-visible { outline: 2px solid var(--doc-accent); outline-offset: -2px; }
2431
2519
 
2520
+ /* A cell's words break as the page's do (word-break inherited: an ordinary word whole at a line's
2521
+ end, a long run anywhere in the span the kit holds it in, .doc-long-run, page.css), a word wider
2522
+ than its column anywhere too (overflow-wrap); what a table keeps whole says so below: its headers,
2523
+ a short field, inline code. */
2432
2524
  .doc-table th,
2433
2525
  .doc-table td {
2434
2526
  padding: 10px 9px; /* Notion's 9px at the sides */
@@ -2440,7 +2532,6 @@ figure:is(.doc-image, .doc-file, .doc-bookmark, .doc-embed):not(:has(> *)) { dis
2440
2532
  text-align: left;
2441
2533
  vertical-align: top;
2442
2534
  white-space: normal;
2443
- word-break: break-word;
2444
2535
  }
2445
2536
  /* A cell left empty is one line high, as a text block left empty is (flow.css): a row of empty cells
2446
2537
  is as tall as a row of words from the first paint on, not flat until the page editor makes the
@@ -2471,10 +2562,13 @@ figure:is(.doc-image, .doc-file, .doc-bookmark, .doc-embed):not(:has(> *)) { dis
2471
2562
 
2472
2563
  .doc-table--auto { table-layout: fixed; max-width: none; }
2473
2564
  .doc-table [data-column-kind="compact"] { white-space: nowrap; word-break: normal; }
2474
- .doc-table [data-column-kind="narrative"] { overflow-wrap: break-word; word-break: normal; }
2565
+ .doc-table [data-column-kind="narrative"] { overflow-wrap: break-word; }
2566
+ /* No word-break here: a compact cell that wraps (data-column-wrap="") keeps the compact rule's normal
2567
+ above, a column of paths (token-heavy) the page's (its long runs breaking anywhere). */
2475
2568
  .doc-table [data-column-kind="token-heavy"],
2476
- .doc-table [data-column-wrap] { white-space: normal; overflow-wrap: anywhere; word-break: normal; }
2569
+ .doc-table [data-column-wrap] { white-space: normal; overflow-wrap: anywhere; }
2477
2570
  .doc-table [data-column-kind] code { white-space: inherit; }
2571
+ /* A short field (compact) keeps its pieces whole (a number, (1606)): its column's floor is the widest of them (layout.js). */
2478
2572
  /* Words kept whole (keep-all: a line breaks at a space or a punctuation mark, never between the
2479
2573
  characters of a Chinese word): a header's (标准差, 区间, a unit in brackets: (%)) and a short
2480
2574
  field's that wraps (卷数 beside columns of prose: 六十卷、 / 目录一卷; tables/layout.js), where its
@@ -2483,6 +2577,9 @@ figure:is(.doc-image, .doc-file, .doc-bookmark, .doc-embed):not(:has(> *)) { dis
2483
2577
  the browser lays the table out) keeps them whole too. */
2484
2578
  .doc-table th:not([data-column-wrap]),
2485
2579
  .doc-table [data-column-wrap="words"] { word-break: keep-all; }
2580
+ /* What a header or a short field keeps whole, a long run in it too: the span the kit holds the run in
2581
+ (.doc-long-run, base.css) breaks as its cell does. */
2582
+ .doc-table :is(th:not([data-column-wrap]), [data-column-wrap="words"], [data-column-kind="compact"]) .doc-long-run { word-break: inherit; }
2486
2583
  /* Inline code in a cell breaks only after a slash or at a space (a path at its folders, never at a
2487
2584
  hyphen or inside a word): its runs (tables/cells.js, as the page renders; not while the page
2488
2585
  editor edits the cell) each kept on one line, a break allowed between them. A column the kit sizes
@@ -2532,7 +2629,7 @@ figure:is(.doc-image, .doc-file, .doc-bookmark, .doc-embed):not(:has(> *)) { dis
2532
2629
  /* A cell's look (the page editor's table tools write these classes on its td or th): a text color
2533
2630
  (base.css), a fill over the whole cell (base.css's: a cell is square, and one that sticks wears it too, above), bold words (the words
2534
2631
  typed in it later too), and an alignment over the kit's own (a numeric column's centre), a vertical one (the kit's: top). A header
2535
- row's and column's look is these: .doc-highlight-gray and .doc-bold. */
2632
+ row's look is these: .doc-highlight-gray and .doc-bold (a header column has none of its own). */
2536
2633
  .doc-table :is(td, th).doc-bold { font-weight: 600; }
2537
2634
  .doc-table :is(td, th).doc-align-left { text-align: left; }
2538
2635
  .doc-table :is(td, th).doc-align-center { text-align: center; }
@@ -2629,19 +2726,22 @@ figure:is(.doc-image, .doc-file, .doc-bookmark, .doc-embed):not(:has(> *)) { dis
2629
2726
  .doc-table-meta > span:not([class]) + :not([class]):last-child { display: block; float: none; margin: 4px 0 0; }
2630
2727
  }
2631
2728
 
2632
- /* 提示块: inline text set apart on a fill, with a line at its left in that fill's deep shade. Its
2633
- color is the background it is given (颜色 in the page editor's block menu, base.css's classes:
2634
- --doc-fill and --doc-fill-deep), and with none the palette's blue (src/shared/colors.mjs),
2635
- the same as one given that blue. A text color colors its words only. Its corners are square;
2636
- the editor's selection lies 6px past it, round (--doc-box-reach: what it wraps, base.css). */
2729
+ /* 提示块: blocks set apart on a fill, with a line at its left in that fill's deep shade. It holds
2730
+ blocks as a highlight block does (its paragraphs, lists, code…: they read as in any flow, flow.css,
2731
+ its first and last taking no margin outside them, highlight.css); one written the old way, words
2732
+ straight in it, shows them as its one paragraph. Its color is the background it is given (颜色 in
2733
+ the page editor's block menu, base.css's classes: --doc-fill and --doc-fill-deep), and with none
2734
+ the palette's blue (src/shared/colors.mjs), the same as one given that blue; its fill is that
2735
+ color taken a little toward the page's background (the user's, 2026-11-07: a little lighter),
2736
+ its line that color's deep shade as it is. A text color colors its words only. Its corners are
2737
+ square; the editor's selection lies 6px past it, round (--doc-box-reach: what it wraps, base.css). */
2637
2738
 
2638
2739
  .doc-callout {
2639
2740
  --doc-box-reach: 6px;
2640
2741
  margin-block: var(--doc-component-gap);
2641
2742
  padding: 12px 14px;
2642
2743
  border-left: 3px solid var(--doc-fill-deep, light-dark(#387dc9, #5e87c9));
2643
- background: var(--doc-fill, light-dark(#e5f2fc, #233850));
2644
- line-height: 1.6;
2744
+ background: color-mix(in srgb, var(--doc-fill, light-dark(#e5f2fc, #233850)) 70%, var(--doc-bg));
2645
2745
  }
2646
2746
 
2647
2747
  /* 折叠列表: a disclosure, its title row with an arrow, and its content region, a flow. It is drawn
@@ -2681,17 +2781,16 @@ figure:is(.doc-image, .doc-file, .doc-bookmark, .doc-embed):not(:has(> *)) { dis
2681
2781
  }
2682
2782
 
2683
2783
  .doc-details > summary::-webkit-details-marker { display: none; }
2784
+ /* Its words whole as the page's, a long run breaking anywhere (page.css); overflow-wrap: anywhere keeps a word from widening the title's column. */
2684
2785
  .doc-details-summary-label {
2685
2786
  min-width: 0;
2686
2787
  padding: var(--doc-block-title-padding) 16px var(--doc-block-title-padding) 0;
2687
2788
  overflow-wrap: anywhere;
2688
- word-break: break-word;
2689
2789
  }
2690
2790
 
2691
2791
  .doc-details-summary-label code {
2692
2792
  white-space: normal;
2693
2793
  overflow-wrap: anywhere;
2694
- word-break: break-word;
2695
2794
  }
2696
2795
 
2697
2796
  /* The code block's fold arrow: a small filled triangle, pointing right while the block is closed,
@@ -2732,40 +2831,52 @@ figure:is(.doc-image, .doc-file, .doc-bookmark, .doc-embed):not(:has(> *)) { dis
2732
2831
  there, so this is all the look it has, and what reads by itself reads: a title, paragraphs, lists,
2733
2832
  a table, what a script of data holds as the kit draws it (doc-component-data: a table, keys beside
2734
2833
  their values, a list), what is wider than the page scrolling in it. In the preview a note above it
2735
- says why, to who writes the page (data-doc-dev: no export takes it, nor a presentation or paper). */
2834
+ says why, to who writes the page (data-doc-dev: no export takes it, nor a presentation or paper).
2835
+ What its slots hold (data-doc-slot) is the document's blocks, which read as in any flow (flow.css)
2836
+ whatever state it is in: this look stops at a slot (@scope … to; a browser without @scope shows
2837
+ it with none of this look, what it holds all there). */
2736
2838
 
2737
2839
  [data-doc-component] {
2738
2840
  margin: var(--doc-block-gap) 0;
2739
2841
  }
2740
- [data-doc-fallback] {
2741
- overflow-x: auto;
2742
- }
2743
- [data-doc-fallback] :where(img, svg, video, iframe) {
2744
- max-width: 100%;
2745
- }
2746
- [data-doc-fallback] :where(img, video) {
2747
- height: auto;
2748
- }
2749
- [data-doc-fallback] :where(h1, h2, h3, h4) {
2750
- margin: 12px 0 6px;
2751
- color: var(--doc-text);
2752
- font-size: var(--doc-h4-font-size);
2753
- line-height: var(--doc-h4-line-height);
2754
- font-weight: 600;
2755
- }
2756
- [data-doc-fallback] :where(p, ul, ol, dl, table) {
2757
- margin: 0 0 8px;
2842
+ /* A slot holds the document's blocks: they read as in any flow (flow.css), the first and the last flush with it. */
2843
+ [data-doc-slot] > :where(:first-child) {
2844
+ margin-top: 0;
2758
2845
  }
2759
- [data-doc-fallback] :where(ul, ol) {
2760
- padding-inline-start: 1.625em;
2846
+ [data-doc-slot] > :where(:last-child) {
2847
+ margin-bottom: 0;
2761
2848
  }
2762
- [data-doc-fallback] :where(table) {
2763
- border-collapse: collapse;
2849
+ [data-doc-fallback] {
2850
+ overflow-x: auto;
2764
2851
  }
2765
- [data-doc-fallback] :where(th, td) {
2766
- padding: 4px 8px;
2767
- border: 1px solid var(--doc-border);
2768
- text-align: start;
2852
+ @scope ([data-doc-fallback]) to ([data-doc-slot]) {
2853
+ :scope :where(img, svg, video, iframe) {
2854
+ max-width: 100%;
2855
+ }
2856
+ :scope :where(img, video) {
2857
+ height: auto;
2858
+ }
2859
+ :scope :where(h1, h2, h3, h4) {
2860
+ margin: 12px 0 6px;
2861
+ color: var(--doc-text);
2862
+ font-size: var(--doc-h4-font-size);
2863
+ line-height: var(--doc-h4-line-height);
2864
+ font-weight: 600;
2865
+ }
2866
+ :scope :where(p, ul, ol, dl, table) {
2867
+ margin: 0 0 8px;
2868
+ }
2869
+ :scope :where(ul, ol) {
2870
+ padding-inline-start: 1.625em;
2871
+ }
2872
+ :scope :where(table) {
2873
+ border-collapse: collapse;
2874
+ }
2875
+ :scope :where(th, td) {
2876
+ padding: 4px 8px;
2877
+ border: 1px solid var(--doc-border);
2878
+ text-align: start;
2879
+ }
2769
2880
  }
2770
2881
  .doc-component-data :where(ul, dl, table) {
2771
2882
  margin: 0;