edgepress 2026.10.1 → 2026.10.13

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 (485) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +216 -16
  3. package/config.yml +99 -127
  4. package/content/assets/edgepress/brand/avatar.png +0 -0
  5. package/content/assets/edgepress/brand/deploy-esa.svg +1 -0
  6. package/content/assets/edgepress/brand/home-hero-768.webp +0 -0
  7. package/content/assets/edgepress/brand/home-hero.png +0 -0
  8. package/content/assets/edgepress/brand/home-hero.webp +0 -0
  9. package/content/assets/edgepress/brand/mascot.png +0 -0
  10. package/content/assets/edgepress/brand/mascot.webp +0 -0
  11. package/content/assets/edgepress/brand/og-image.png +0 -0
  12. package/content/assets/edgepress/brand/og-image.webp +0 -0
  13. package/content/assets/edgepress/brand/sources/edgepress-avatar-master.png +0 -0
  14. package/content/assets/edgepress/brand/sources/export-manifest.json +181 -0
  15. package/content/assets/edgepress/brand/sources/prompts.json +12 -0
  16. package/content/assets/edgepress/favicon/apple-touch-icon.png +0 -0
  17. package/content/assets/edgepress/favicon/favicon-16.png +0 -0
  18. package/content/assets/edgepress/favicon/favicon-32.png +0 -0
  19. package/content/assets/edgepress/favicon/favicon-48.png +0 -0
  20. package/content/assets/edgepress/favicon/favicon-64.png +0 -0
  21. package/content/assets/edgepress/favicon/favicon.ico +0 -0
  22. package/content/assets/edgepress/icons/LICENSE.txt +43 -0
  23. package/content/assets/edgepress/icons/arrow-right.svg +16 -0
  24. package/content/assets/edgepress/icons/arrow-up-right.svg +16 -0
  25. package/content/assets/edgepress/icons/book-open.svg +16 -0
  26. package/content/assets/edgepress/icons/check-circle.svg +16 -0
  27. package/content/assets/edgepress/icons/check.svg +15 -0
  28. package/content/assets/edgepress/icons/cloud.svg +15 -0
  29. package/content/assets/edgepress/icons/code.svg +16 -0
  30. package/content/assets/edgepress/icons/cpu.svg +28 -0
  31. package/content/assets/edgepress/icons/file-text.svg +19 -0
  32. package/content/assets/edgepress/icons/github.svg +17 -0
  33. package/content/assets/edgepress/icons/globe.svg +17 -0
  34. package/content/assets/edgepress/icons/help-circle.svg +17 -0
  35. package/content/assets/edgepress/icons/home.svg +16 -0
  36. package/content/assets/edgepress/icons/layers.svg +17 -0
  37. package/content/assets/edgepress/icons/layout-grid.svg +18 -0
  38. package/content/assets/edgepress/icons/mail.svg +16 -0
  39. package/content/assets/edgepress/icons/newspaper.svg +18 -0
  40. package/content/assets/edgepress/icons/palette.svg +19 -0
  41. package/content/assets/edgepress/icons/plug.svg +18 -0
  42. package/content/assets/edgepress/icons/provenance.json +8 -0
  43. package/content/assets/edgepress/icons/puzzle.svg +15 -0
  44. package/content/assets/edgepress/icons/rocket.svg +18 -0
  45. package/content/assets/edgepress/icons/rss.svg +17 -0
  46. package/content/assets/edgepress/icons/search.svg +16 -0
  47. package/content/assets/edgepress/icons/settings.svg +16 -0
  48. package/content/assets/edgepress/icons/shield-check.svg +16 -0
  49. package/content/assets/edgepress/icons/sparkles.svg +18 -0
  50. package/content/assets/edgepress/icons/terminal.svg +16 -0
  51. package/content/assets/edgepress/icons/x.svg +16 -0
  52. package/{static → content/assets}/edgepress-markdown-guide.svg +1 -1
  53. package/content/assets/images/previews/edgepress-en.webp +0 -0
  54. package/content/assets/images/previews/edgepress-revisions-en.png +0 -0
  55. package/content/assets/images/previews/edgepress-workflow-en.90f4650b21013786.gif +0 -0
  56. package/content/assets/images/previews/edgepress-workflow-zh.41f1e0a685f47267.gif +0 -0
  57. package/content/assets/images/previews/edgepress-zh.webp +0 -0
  58. package/content/assets/images/previews/provenance.json +49 -0
  59. package/content/guides/markdown-media.md +38 -0
  60. package/content/guides/platforms.md +15 -0
  61. package/content/guides/product-demos.md +37 -0
  62. package/content/guides/zh-cn.md +62 -0
  63. package/content/pages/deployment/en.json +74 -0
  64. package/content/pages/deployment/zh-cn.json +74 -0
  65. package/content/pages/home/en.json +248 -0
  66. package/content/pages/home/zh-cn.json +248 -0
  67. package/content/pages/local-tools/en.json +14 -0
  68. package/content/pages/local-tools/zh-cn.json +14 -0
  69. package/content/pages/page-authoring/en.json +107 -0
  70. package/content/pages/page-authoring/zh-cn.json +107 -0
  71. package/content/pages/plugin-development/en.json +202 -0
  72. package/content/pages/plugin-development/zh-cn.json +202 -0
  73. package/content/pages/privacy-policy/en.json +171 -0
  74. package/content/pages/privacy-policy/zh-cn.json +171 -0
  75. package/content/pages/project-introduction/en.json +158 -0
  76. package/content/pages/project-introduction/zh-cn.json +158 -0
  77. package/content/pages/quick-start/en.json +325 -0
  78. package/content/pages/quick-start/zh-cn.json +325 -0
  79. package/content/pages/theme-development/en.json +353 -0
  80. package/content/pages/theme-development/zh-cn.json +349 -0
  81. package/content/posts/2026-09-24-edgepress-release-2026-9-1/en.md +1 -1
  82. package/content/posts/2026-09-24-edgepress-release-2026-9-1/zh-cn.md +1 -1
  83. package/content/posts/2026-10-03-edgepress-release-2026-10-3/en.md +16 -0
  84. package/content/posts/2026-10-03-edgepress-release-2026-10-3/zh-cn.md +16 -0
  85. package/content/posts/2026-10-03-edgepress-release-202610-4/en.md +22 -0
  86. package/content/posts/2026-10-03-edgepress-release-202610-4/zh-cn.md +20 -0
  87. package/content/posts/2026-10-03-edgepress-release-202610-5/en.md +15 -0
  88. package/content/posts/2026-10-03-edgepress-release-202610-5/zh-cn.md +15 -0
  89. package/edgeone.json +43 -0
  90. package/esa.jsonc +9 -0
  91. package/languages/base/en.json +75 -10
  92. package/languages/packs/zh-CN.json +74 -9
  93. package/netlify.toml +6 -0
  94. package/package.json +37 -6
  95. package/plugins/consent/index.js +10 -17
  96. package/project-compatibility.json +142 -25
  97. package/schemas/pages.schema.json +74 -0
  98. package/src/assets.js +146 -18
  99. package/src/browser-audit.js +158 -0
  100. package/src/build.js +34 -9
  101. package/src/cli.js +46 -41
  102. package/src/config.js +114 -63
  103. package/src/consent-csp.js +137 -0
  104. package/src/content.js +55 -30
  105. package/src/data-saver.js +194 -0
  106. package/src/deploy.js +28 -0
  107. package/src/document.js +44 -0
  108. package/src/embed.js +60 -0
  109. package/src/generators.js +101 -59
  110. package/src/i18n.js +19 -3
  111. package/src/icons.js +5 -4
  112. package/src/image-dimensions.js +17 -0
  113. package/src/local-tool.js +29 -0
  114. package/src/maintenance.js +25 -8
  115. package/src/markdown-fixture.js +20 -0
  116. package/src/markdown.js +80 -16
  117. package/src/media-assets.js +19 -0
  118. package/src/media-viewer.js +47 -0
  119. package/src/oembed.js +53 -0
  120. package/src/page-blocks.js +124 -54
  121. package/src/page-check.js +29 -39
  122. package/src/plugin-api.js +7 -1
  123. package/src/post-details.js +60 -0
  124. package/src/post-template.js +5 -0
  125. package/src/publication-time.js +47 -0
  126. package/src/report-path.js +19 -0
  127. package/src/report-visuals.js +91 -18
  128. package/src/revision-cards.js +30 -0
  129. package/src/revision-images.js +44 -0
  130. package/src/revisions.js +77 -0
  131. package/src/rss.js +100 -0
  132. package/src/service-block.js +18 -0
  133. package/src/theme.js +59 -9
  134. package/src/video-metadata.js +36 -0
  135. package/static/edgepress/data-saver.css +12 -0
  136. package/static/edgepress/data-saver.js +333 -0
  137. package/static/edgepress/document-viewer.js +35 -0
  138. package/static/edgepress/external-links-policy.js +14 -0
  139. package/static/edgepress/external-links.css +13 -0
  140. package/static/edgepress/external-links.js +120 -0
  141. package/static/edgepress/fonts/faces.css +2217 -0
  142. package/static/edgepress/fonts/noto-sans-OFL.txt +93 -0
  143. package/static/edgepress/fonts/noto-sans-cyrillic-ext-wght-normal.82ff72b28e6610f2.woff2 +0 -0
  144. package/static/edgepress/fonts/noto-sans-cyrillic-wght-normal.6ab64433de6077ca.woff2 +0 -0
  145. package/static/edgepress/fonts/noto-sans-devanagari-wght-normal.ea6a530b75d93de7.woff2 +0 -0
  146. package/static/edgepress/fonts/noto-sans-greek-ext-wght-normal.790b255c10c32e0b.woff2 +0 -0
  147. package/static/edgepress/fonts/noto-sans-greek-wght-normal.7f655207c2f6c140.woff2 +0 -0
  148. package/static/edgepress/fonts/noto-sans-latin-ext-wght-normal.6d5a79315528df19.woff2 +0 -0
  149. package/static/edgepress/fonts/noto-sans-latin-wght-normal.51ca196f49a33e79.woff2 +0 -0
  150. package/static/edgepress/fonts/noto-sans-sc-100-wght-normal.ad5f29028d5699a5.woff2 +0 -0
  151. package/static/edgepress/fonts/noto-sans-sc-101-wght-normal.e189b81fc22ca6af.woff2 +0 -0
  152. package/static/edgepress/fonts/noto-sans-sc-102-wght-normal.941c0c2971fc1d6d.woff2 +0 -0
  153. package/static/edgepress/fonts/noto-sans-sc-103-wght-normal.bafbd591af6493ff.woff2 +0 -0
  154. package/static/edgepress/fonts/noto-sans-sc-104-wght-normal.b0bf80ced89dd61b.woff2 +0 -0
  155. package/static/edgepress/fonts/noto-sans-sc-105-wght-normal.8d8b4e6f4a00621d.woff2 +0 -0
  156. package/static/edgepress/fonts/noto-sans-sc-106-wght-normal.bae74acc629d2e74.woff2 +0 -0
  157. package/static/edgepress/fonts/noto-sans-sc-107-wght-normal.a42eff5010de7b0d.woff2 +0 -0
  158. package/static/edgepress/fonts/noto-sans-sc-108-wght-normal.91882203459867be.woff2 +0 -0
  159. package/static/edgepress/fonts/noto-sans-sc-109-wght-normal.a91f8b038e5ce108.woff2 +0 -0
  160. package/static/edgepress/fonts/noto-sans-sc-110-wght-normal.bbca9081655c4523.woff2 +0 -0
  161. package/static/edgepress/fonts/noto-sans-sc-111-wght-normal.372be010ac0e87cb.woff2 +0 -0
  162. package/static/edgepress/fonts/noto-sans-sc-112-wght-normal.34a4580239eae8dc.woff2 +0 -0
  163. package/static/edgepress/fonts/noto-sans-sc-113-wght-normal.614ab8f616352583.woff2 +0 -0
  164. package/static/edgepress/fonts/noto-sans-sc-114-wght-normal.cf7b8344807a316e.woff2 +0 -0
  165. package/static/edgepress/fonts/noto-sans-sc-115-wght-normal.fb29957c7adccb9a.woff2 +0 -0
  166. package/static/edgepress/fonts/noto-sans-sc-116-wght-normal.a98dc5a726f82141.woff2 +0 -0
  167. package/static/edgepress/fonts/noto-sans-sc-117-wght-normal.d94b5af0c14838af.woff2 +0 -0
  168. package/static/edgepress/fonts/noto-sans-sc-118-wght-normal.76c9ddb85ae4578c.woff2 +0 -0
  169. package/static/edgepress/fonts/noto-sans-sc-119-wght-normal.b3b2374881f4cd93.woff2 +0 -0
  170. package/static/edgepress/fonts/noto-sans-sc-21-wght-normal.c1409c43e55ecff2.woff2 +0 -0
  171. package/static/edgepress/fonts/noto-sans-sc-22-wght-normal.77037ed42ff4e7b0.woff2 +0 -0
  172. package/static/edgepress/fonts/noto-sans-sc-23-wght-normal.38d0df21ac374e93.woff2 +0 -0
  173. package/static/edgepress/fonts/noto-sans-sc-24-wght-normal.8fa21e7e457acf3e.woff2 +0 -0
  174. package/static/edgepress/fonts/noto-sans-sc-25-wght-normal.f760b7a3871d214d.woff2 +0 -0
  175. package/static/edgepress/fonts/noto-sans-sc-26-wght-normal.be8386e7bd7facfe.woff2 +0 -0
  176. package/static/edgepress/fonts/noto-sans-sc-27-wght-normal.4895abcaddbd162e.woff2 +0 -0
  177. package/static/edgepress/fonts/noto-sans-sc-28-wght-normal.82540b6201a9b9ad.woff2 +0 -0
  178. package/static/edgepress/fonts/noto-sans-sc-29-wght-normal.ff21d8fcc60ce391.woff2 +0 -0
  179. package/static/edgepress/fonts/noto-sans-sc-30-wght-normal.1f76f6ffded00b9e.woff2 +0 -0
  180. package/static/edgepress/fonts/noto-sans-sc-31-wght-normal.e6c25be1bb08a63a.woff2 +0 -0
  181. package/static/edgepress/fonts/noto-sans-sc-32-wght-normal.0cda750d7d04a4e1.woff2 +0 -0
  182. package/static/edgepress/fonts/noto-sans-sc-33-wght-normal.b9732b5606bd87c5.woff2 +0 -0
  183. package/static/edgepress/fonts/noto-sans-sc-34-wght-normal.38aa326b4c84902a.woff2 +0 -0
  184. package/static/edgepress/fonts/noto-sans-sc-35-wght-normal.bd98226c8e0aa808.woff2 +0 -0
  185. package/static/edgepress/fonts/noto-sans-sc-36-wght-normal.0db1ca695a491d37.woff2 +0 -0
  186. package/static/edgepress/fonts/noto-sans-sc-37-wght-normal.8df409a4e0a237c2.woff2 +0 -0
  187. package/static/edgepress/fonts/noto-sans-sc-38-wght-normal.672d2d994994a3c3.woff2 +0 -0
  188. package/static/edgepress/fonts/noto-sans-sc-39-wght-normal.272d6d0e153f56e8.woff2 +0 -0
  189. package/static/edgepress/fonts/noto-sans-sc-4-wght-normal.9fafd93ac77b81ff.woff2 +0 -0
  190. package/static/edgepress/fonts/noto-sans-sc-40-wght-normal.5b9ef1ed48420aa7.woff2 +0 -0
  191. package/static/edgepress/fonts/noto-sans-sc-41-wght-normal.30aee47f660fd88a.woff2 +0 -0
  192. package/static/edgepress/fonts/noto-sans-sc-42-wght-normal.ec0014830db682b6.woff2 +0 -0
  193. package/static/edgepress/fonts/noto-sans-sc-43-wght-normal.43df2b5dad9bb835.woff2 +0 -0
  194. package/static/edgepress/fonts/noto-sans-sc-44-wght-normal.acaa6195041b1a92.woff2 +0 -0
  195. package/static/edgepress/fonts/noto-sans-sc-45-wght-normal.8cdb9903f770db21.woff2 +0 -0
  196. package/static/edgepress/fonts/noto-sans-sc-46-wght-normal.6590d0a6fe94571c.woff2 +0 -0
  197. package/static/edgepress/fonts/noto-sans-sc-47-wght-normal.b05afdd32b3bf722.woff2 +0 -0
  198. package/static/edgepress/fonts/noto-sans-sc-48-wght-normal.c9585f7d070700be.woff2 +0 -0
  199. package/static/edgepress/fonts/noto-sans-sc-49-wght-normal.4943895a4dfa5dcf.woff2 +0 -0
  200. package/static/edgepress/fonts/noto-sans-sc-5-wght-normal.e64f57937e3ae4fe.woff2 +0 -0
  201. package/static/edgepress/fonts/noto-sans-sc-50-wght-normal.13e51063d7743cfe.woff2 +0 -0
  202. package/static/edgepress/fonts/noto-sans-sc-51-wght-normal.fd4df1f02c2cb4d7.woff2 +0 -0
  203. package/static/edgepress/fonts/noto-sans-sc-52-wght-normal.06999a39c4c3a7ea.woff2 +0 -0
  204. package/static/edgepress/fonts/noto-sans-sc-53-wght-normal.767b7b9864658d91.woff2 +0 -0
  205. package/static/edgepress/fonts/noto-sans-sc-54-wght-normal.4cd00537a46f6f1a.woff2 +0 -0
  206. package/static/edgepress/fonts/noto-sans-sc-55-wght-normal.0118ec5d8c30b197.woff2 +0 -0
  207. package/static/edgepress/fonts/noto-sans-sc-56-wght-normal.a3e4a78929826930.woff2 +0 -0
  208. package/static/edgepress/fonts/noto-sans-sc-57-wght-normal.7623501009e4a6db.woff2 +0 -0
  209. package/static/edgepress/fonts/noto-sans-sc-58-wght-normal.56ae1a59a32e4a25.woff2 +0 -0
  210. package/static/edgepress/fonts/noto-sans-sc-59-wght-normal.7a377a40e99fd9bc.woff2 +0 -0
  211. package/static/edgepress/fonts/noto-sans-sc-6-wght-normal.17e15c4f0a5bfd92.woff2 +0 -0
  212. package/static/edgepress/fonts/noto-sans-sc-60-wght-normal.3657f66babdf6aff.woff2 +0 -0
  213. package/static/edgepress/fonts/noto-sans-sc-61-wght-normal.23919a2eb11d25dd.woff2 +0 -0
  214. package/static/edgepress/fonts/noto-sans-sc-62-wght-normal.a901edf25bc1cfae.woff2 +0 -0
  215. package/static/edgepress/fonts/noto-sans-sc-63-wght-normal.92f56f713cc0b62f.woff2 +0 -0
  216. package/static/edgepress/fonts/noto-sans-sc-64-wght-normal.4929c9f39a5a4bd9.woff2 +0 -0
  217. package/static/edgepress/fonts/noto-sans-sc-65-wght-normal.8daa61282fb62a11.woff2 +0 -0
  218. package/static/edgepress/fonts/noto-sans-sc-66-wght-normal.6479166925eb462b.woff2 +0 -0
  219. package/static/edgepress/fonts/noto-sans-sc-67-wght-normal.a6b0e11c4c761ffd.woff2 +0 -0
  220. package/static/edgepress/fonts/noto-sans-sc-68-wght-normal.65b77f1fe9d68dae.woff2 +0 -0
  221. package/static/edgepress/fonts/noto-sans-sc-69-wght-normal.b34f765cbbf4d02e.woff2 +0 -0
  222. package/static/edgepress/fonts/noto-sans-sc-70-wght-normal.a99d55c00e4f95b7.woff2 +0 -0
  223. package/static/edgepress/fonts/noto-sans-sc-71-wght-normal.3298bed30dc8d233.woff2 +0 -0
  224. package/static/edgepress/fonts/noto-sans-sc-72-wght-normal.6597209ca9707726.woff2 +0 -0
  225. package/static/edgepress/fonts/noto-sans-sc-73-wght-normal.e7ac1d4930eabd78.woff2 +0 -0
  226. package/static/edgepress/fonts/noto-sans-sc-74-wght-normal.1f0287be83a28e7a.woff2 +0 -0
  227. package/static/edgepress/fonts/noto-sans-sc-75-wght-normal.d9a4bb7bcc2be578.woff2 +0 -0
  228. package/static/edgepress/fonts/noto-sans-sc-76-wght-normal.5a019946bcadcec6.woff2 +0 -0
  229. package/static/edgepress/fonts/noto-sans-sc-77-wght-normal.7c445e85d04f5319.woff2 +0 -0
  230. package/static/edgepress/fonts/noto-sans-sc-78-wght-normal.7d4afb70f641781c.woff2 +0 -0
  231. package/static/edgepress/fonts/noto-sans-sc-79-wght-normal.5798753a721bb4ec.woff2 +0 -0
  232. package/static/edgepress/fonts/noto-sans-sc-80-wght-normal.db887159ca6e46f3.woff2 +0 -0
  233. package/static/edgepress/fonts/noto-sans-sc-81-wght-normal.71e5743bbd225b3d.woff2 +0 -0
  234. package/static/edgepress/fonts/noto-sans-sc-82-wght-normal.8c5094c3785fd04f.woff2 +0 -0
  235. package/static/edgepress/fonts/noto-sans-sc-83-wght-normal.4a60a1ccba905284.woff2 +0 -0
  236. package/static/edgepress/fonts/noto-sans-sc-84-wght-normal.3ed54e59ef4758e3.woff2 +0 -0
  237. package/static/edgepress/fonts/noto-sans-sc-85-wght-normal.e87e0a1342e1778c.woff2 +0 -0
  238. package/static/edgepress/fonts/noto-sans-sc-86-wght-normal.6d3ac3e20959dbcb.woff2 +0 -0
  239. package/static/edgepress/fonts/noto-sans-sc-87-wght-normal.0eeffd5daad5c17b.woff2 +0 -0
  240. package/static/edgepress/fonts/noto-sans-sc-88-wght-normal.b1d9582dfa268463.woff2 +0 -0
  241. package/static/edgepress/fonts/noto-sans-sc-89-wght-normal.8b437aeb9e9fcb5a.woff2 +0 -0
  242. package/static/edgepress/fonts/noto-sans-sc-90-wght-normal.83b0a59e0a5e045a.woff2 +0 -0
  243. package/static/edgepress/fonts/noto-sans-sc-91-wght-normal.382f72b98d4bb9d7.woff2 +0 -0
  244. package/static/edgepress/fonts/noto-sans-sc-97-wght-normal.5e52856457c5cdab.woff2 +0 -0
  245. package/static/edgepress/fonts/noto-sans-sc-98-wght-normal.ffded4e7fd560d93.woff2 +0 -0
  246. package/static/edgepress/fonts/noto-sans-sc-99-wght-normal.54e302c23f11a8fd.woff2 +0 -0
  247. package/static/edgepress/fonts/noto-sans-sc-OFL.txt +93 -0
  248. package/static/edgepress/fonts/noto-sans-sc-cyrillic-wght-normal.5932d441e7126669.woff2 +0 -0
  249. package/static/edgepress/fonts/noto-sans-sc-latin-ext-wght-normal.e316201f3fc493d1.woff2 +0 -0
  250. package/static/edgepress/fonts/noto-sans-sc-latin-wght-normal.c1d919c8701a86ed.woff2 +0 -0
  251. package/static/edgepress/fonts/noto-sans-sc-vietnamese-wght-normal.cba3d00c8db989f0.woff2 +0 -0
  252. package/static/edgepress/fonts/noto-sans-tc-0-wght-normal.63c21eda5d20203f.woff2 +0 -0
  253. package/static/edgepress/fonts/noto-sans-tc-100-wght-normal.87a7c76301c24a28.woff2 +0 -0
  254. package/static/edgepress/fonts/noto-sans-tc-101-wght-normal.c9e83fc4ffd53746.woff2 +0 -0
  255. package/static/edgepress/fonts/noto-sans-tc-102-wght-normal.9a00ae0e5735852b.woff2 +0 -0
  256. package/static/edgepress/fonts/noto-sans-tc-103-wght-normal.7cfe93b3221f4def.woff2 +0 -0
  257. package/static/edgepress/fonts/noto-sans-tc-104-wght-normal.2d5ac7497d84cb99.woff2 +0 -0
  258. package/static/edgepress/fonts/noto-sans-tc-105-wght-normal.0989885bb16bcd9b.woff2 +0 -0
  259. package/static/edgepress/fonts/noto-sans-tc-106-wght-normal.1faa921b035064e7.woff2 +0 -0
  260. package/static/edgepress/fonts/noto-sans-tc-107-wght-normal.2f6006745ae16d69.woff2 +0 -0
  261. package/static/edgepress/fonts/noto-sans-tc-108-wght-normal.a61e48c10a2cf4b9.woff2 +0 -0
  262. package/static/edgepress/fonts/noto-sans-tc-109-wght-normal.f28c767724736d2d.woff2 +0 -0
  263. package/static/edgepress/fonts/noto-sans-tc-110-wght-normal.4b04bd88c3dc7c5d.woff2 +0 -0
  264. package/static/edgepress/fonts/noto-sans-tc-111-wght-normal.b6251e1967932a52.woff2 +0 -0
  265. package/static/edgepress/fonts/noto-sans-tc-112-wght-normal.e264513b32f90660.woff2 +0 -0
  266. package/static/edgepress/fonts/noto-sans-tc-113-wght-normal.46cb347d88f3338e.woff2 +0 -0
  267. package/static/edgepress/fonts/noto-sans-tc-114-wght-normal.9f9e1e0d0ab2aeb4.woff2 +0 -0
  268. package/static/edgepress/fonts/noto-sans-tc-115-wght-normal.653dd2ab7d551b40.woff2 +0 -0
  269. package/static/edgepress/fonts/noto-sans-tc-116-wght-normal.4718bf3627191297.woff2 +0 -0
  270. package/static/edgepress/fonts/noto-sans-tc-117-wght-normal.b241a9409682af5f.woff2 +0 -0
  271. package/static/edgepress/fonts/noto-sans-tc-118-wght-normal.fda2800dc1c06852.woff2 +0 -0
  272. package/static/edgepress/fonts/noto-sans-tc-119-wght-normal.948af36bd63a72c7.woff2 +0 -0
  273. package/static/edgepress/fonts/noto-sans-tc-19-wght-normal.62191cdc3a10e60a.woff2 +0 -0
  274. package/static/edgepress/fonts/noto-sans-tc-20-wght-normal.65c90892c2e01657.woff2 +0 -0
  275. package/static/edgepress/fonts/noto-sans-tc-21-wght-normal.d3f59b094c334866.woff2 +0 -0
  276. package/static/edgepress/fonts/noto-sans-tc-22-wght-normal.b1983a041d7e4e1f.woff2 +0 -0
  277. package/static/edgepress/fonts/noto-sans-tc-23-wght-normal.16e2163b66c7732a.woff2 +0 -0
  278. package/static/edgepress/fonts/noto-sans-tc-24-wght-normal.72c8561976116537.woff2 +0 -0
  279. package/static/edgepress/fonts/noto-sans-tc-25-wght-normal.b2948d928ce4dd54.woff2 +0 -0
  280. package/static/edgepress/fonts/noto-sans-tc-26-wght-normal.d583236b90abedc9.woff2 +0 -0
  281. package/static/edgepress/fonts/noto-sans-tc-27-wght-normal.7d6073ba07597c9b.woff2 +0 -0
  282. package/static/edgepress/fonts/noto-sans-tc-28-wght-normal.517204d716b089cd.woff2 +0 -0
  283. package/static/edgepress/fonts/noto-sans-tc-29-wght-normal.10189a8f8ca38099.woff2 +0 -0
  284. package/static/edgepress/fonts/noto-sans-tc-30-wght-normal.695a71d72dfab3f7.woff2 +0 -0
  285. package/static/edgepress/fonts/noto-sans-tc-31-wght-normal.868d59473ef0e73c.woff2 +0 -0
  286. package/static/edgepress/fonts/noto-sans-tc-32-wght-normal.92efa2d4b3702ec0.woff2 +0 -0
  287. package/static/edgepress/fonts/noto-sans-tc-33-wght-normal.d2274bcd5636197d.woff2 +0 -0
  288. package/static/edgepress/fonts/noto-sans-tc-34-wght-normal.1ac8c3718ee2eed2.woff2 +0 -0
  289. package/static/edgepress/fonts/noto-sans-tc-35-wght-normal.00b3df730d5a4c73.woff2 +0 -0
  290. package/static/edgepress/fonts/noto-sans-tc-36-wght-normal.6963feb6c628b81f.woff2 +0 -0
  291. package/static/edgepress/fonts/noto-sans-tc-37-wght-normal.a1b4bd294af24cd1.woff2 +0 -0
  292. package/static/edgepress/fonts/noto-sans-tc-38-wght-normal.8edb2f7f2955921b.woff2 +0 -0
  293. package/static/edgepress/fonts/noto-sans-tc-39-wght-normal.37bf7394eb3148c6.woff2 +0 -0
  294. package/static/edgepress/fonts/noto-sans-tc-40-wght-normal.3efa655bc48f9133.woff2 +0 -0
  295. package/static/edgepress/fonts/noto-sans-tc-41-wght-normal.48d47014544ebd5d.woff2 +0 -0
  296. package/static/edgepress/fonts/noto-sans-tc-42-wght-normal.214c733a59d423e7.woff2 +0 -0
  297. package/static/edgepress/fonts/noto-sans-tc-43-wght-normal.c2c9876f138bb20f.woff2 +0 -0
  298. package/static/edgepress/fonts/noto-sans-tc-44-wght-normal.28928bfea29db06a.woff2 +0 -0
  299. package/static/edgepress/fonts/noto-sans-tc-45-wght-normal.bf3743f8155fa9d2.woff2 +0 -0
  300. package/static/edgepress/fonts/noto-sans-tc-46-wght-normal.06970903593781c3.woff2 +0 -0
  301. package/static/edgepress/fonts/noto-sans-tc-47-wght-normal.8932ed83a91794d4.woff2 +0 -0
  302. package/static/edgepress/fonts/noto-sans-tc-48-wght-normal.dfd9225628bcf234.woff2 +0 -0
  303. package/static/edgepress/fonts/noto-sans-tc-49-wght-normal.c27d341ad39d44eb.woff2 +0 -0
  304. package/static/edgepress/fonts/noto-sans-tc-50-wght-normal.01a0f4e7dfba0a56.woff2 +0 -0
  305. package/static/edgepress/fonts/noto-sans-tc-51-wght-normal.5a30022af3d30e0f.woff2 +0 -0
  306. package/static/edgepress/fonts/noto-sans-tc-52-wght-normal.4884f032342a3274.woff2 +0 -0
  307. package/static/edgepress/fonts/noto-sans-tc-53-wght-normal.537adcae44511270.woff2 +0 -0
  308. package/static/edgepress/fonts/noto-sans-tc-54-wght-normal.6bc8c7d3e47c6fde.woff2 +0 -0
  309. package/static/edgepress/fonts/noto-sans-tc-55-wght-normal.725a48711f1e1997.woff2 +0 -0
  310. package/static/edgepress/fonts/noto-sans-tc-56-wght-normal.f43ecaa73e0cd8fc.woff2 +0 -0
  311. package/static/edgepress/fonts/noto-sans-tc-57-wght-normal.15b24e9d42a3270f.woff2 +0 -0
  312. package/static/edgepress/fonts/noto-sans-tc-58-wght-normal.9b2d8a71667d3da6.woff2 +0 -0
  313. package/static/edgepress/fonts/noto-sans-tc-59-wght-normal.a68535a6b3289d89.woff2 +0 -0
  314. package/static/edgepress/fonts/noto-sans-tc-6-wght-normal.32cece1ae80c4f2b.woff2 +0 -0
  315. package/static/edgepress/fonts/noto-sans-tc-60-wght-normal.3b2c56a921d1cad4.woff2 +0 -0
  316. package/static/edgepress/fonts/noto-sans-tc-61-wght-normal.54f51f80a0740878.woff2 +0 -0
  317. package/static/edgepress/fonts/noto-sans-tc-62-wght-normal.ba029c5bb6c07bf1.woff2 +0 -0
  318. package/static/edgepress/fonts/noto-sans-tc-63-wght-normal.380919beec4c7f3d.woff2 +0 -0
  319. package/static/edgepress/fonts/noto-sans-tc-64-wght-normal.f96fe0be479d201f.woff2 +0 -0
  320. package/static/edgepress/fonts/noto-sans-tc-65-wght-normal.7d544b80701fe678.woff2 +0 -0
  321. package/static/edgepress/fonts/noto-sans-tc-66-wght-normal.fab669c07a1e3bee.woff2 +0 -0
  322. package/static/edgepress/fonts/noto-sans-tc-67-wght-normal.0001bb744743fdfa.woff2 +0 -0
  323. package/static/edgepress/fonts/noto-sans-tc-68-wght-normal.1a57eda03886b43c.woff2 +0 -0
  324. package/static/edgepress/fonts/noto-sans-tc-69-wght-normal.017fecc749bcd6d5.woff2 +0 -0
  325. package/static/edgepress/fonts/noto-sans-tc-7-wght-normal.cd0f0cac743dbbfe.woff2 +0 -0
  326. package/static/edgepress/fonts/noto-sans-tc-70-wght-normal.79fb9d70b9534ec7.woff2 +0 -0
  327. package/static/edgepress/fonts/noto-sans-tc-71-wght-normal.04a6ea581b5f1195.woff2 +0 -0
  328. package/static/edgepress/fonts/noto-sans-tc-72-wght-normal.d3a4eb35499157b7.woff2 +0 -0
  329. package/static/edgepress/fonts/noto-sans-tc-73-wght-normal.d81f8484404ee465.woff2 +0 -0
  330. package/static/edgepress/fonts/noto-sans-tc-74-wght-normal.4a5da9e0c2702f7d.woff2 +0 -0
  331. package/static/edgepress/fonts/noto-sans-tc-75-wght-normal.8b87f9c6c164513a.woff2 +0 -0
  332. package/static/edgepress/fonts/noto-sans-tc-76-wght-normal.a71463dbfd9fa7b5.woff2 +0 -0
  333. package/static/edgepress/fonts/noto-sans-tc-77-wght-normal.d094414ea752cd52.woff2 +0 -0
  334. package/static/edgepress/fonts/noto-sans-tc-78-wght-normal.04f7c97bd9cbc73b.woff2 +0 -0
  335. package/static/edgepress/fonts/noto-sans-tc-79-wght-normal.1ed089d037a02049.woff2 +0 -0
  336. package/static/edgepress/fonts/noto-sans-tc-8-wght-normal.d052677dfb5db5bd.woff2 +0 -0
  337. package/static/edgepress/fonts/noto-sans-tc-80-wght-normal.6d41ca59cfd50442.woff2 +0 -0
  338. package/static/edgepress/fonts/noto-sans-tc-81-wght-normal.f09bd0afa8a58114.woff2 +0 -0
  339. package/static/edgepress/fonts/noto-sans-tc-82-wght-normal.7920841c526b1b02.woff2 +0 -0
  340. package/static/edgepress/fonts/noto-sans-tc-83-wght-normal.0c6f7f82db8da0d8.woff2 +0 -0
  341. package/static/edgepress/fonts/noto-sans-tc-84-wght-normal.f37c0a853b31265e.woff2 +0 -0
  342. package/static/edgepress/fonts/noto-sans-tc-85-wght-normal.4173bff087653b82.woff2 +0 -0
  343. package/static/edgepress/fonts/noto-sans-tc-86-wght-normal.dac35605ebec15c4.woff2 +0 -0
  344. package/static/edgepress/fonts/noto-sans-tc-87-wght-normal.8ac85fdd0b15a6bd.woff2 +0 -0
  345. package/static/edgepress/fonts/noto-sans-tc-88-wght-normal.61625b0b21e8407f.woff2 +0 -0
  346. package/static/edgepress/fonts/noto-sans-tc-89-wght-normal.a1da3dccbf00698e.woff2 +0 -0
  347. package/static/edgepress/fonts/noto-sans-tc-90-wght-normal.bf08f0355222a782.woff2 +0 -0
  348. package/static/edgepress/fonts/noto-sans-tc-91-wght-normal.2ecf295bba2bfaa3.woff2 +0 -0
  349. package/static/edgepress/fonts/noto-sans-tc-92-wght-normal.36508326bb68115f.woff2 +0 -0
  350. package/static/edgepress/fonts/noto-sans-tc-97-wght-normal.c712899e0fc9e947.woff2 +0 -0
  351. package/static/edgepress/fonts/noto-sans-tc-98-wght-normal.13a648e521d18d7f.woff2 +0 -0
  352. package/static/edgepress/fonts/noto-sans-tc-99-wght-normal.7f8c9a777e64159a.woff2 +0 -0
  353. package/static/edgepress/fonts/noto-sans-tc-OFL.txt +93 -0
  354. package/static/edgepress/fonts/noto-sans-tc-cyrillic-wght-normal.dd0980ced8e46cb3.woff2 +0 -0
  355. package/static/edgepress/fonts/noto-sans-tc-latin-ext-wght-normal.817d96335dc52ce6.woff2 +0 -0
  356. package/static/edgepress/fonts/noto-sans-tc-latin-wght-normal.50cb5fb0a522cfaf.woff2 +0 -0
  357. package/static/edgepress/fonts/noto-sans-tc-vietnamese-wght-normal.2a77fb7b70fa304d.woff2 +0 -0
  358. package/static/edgepress/fonts/noto-sans-vietnamese-wght-normal.791e3f213c155a5b.woff2 +0 -0
  359. package/static/edgepress/fonts/noto-serif-OFL.txt +93 -0
  360. package/static/edgepress/fonts/noto-serif-cyrillic-ext-wght-normal.7c7afb20d33e30ec.woff2 +0 -0
  361. package/static/edgepress/fonts/noto-serif-cyrillic-wght-normal.54e3bd0c4a002b0f.woff2 +0 -0
  362. package/static/edgepress/fonts/noto-serif-greek-ext-wght-normal.9b3f4c4ff3adefd2.woff2 +0 -0
  363. package/static/edgepress/fonts/noto-serif-greek-wght-normal.1252037b6f1d6e86.woff2 +0 -0
  364. package/static/edgepress/fonts/noto-serif-latin-ext-wght-normal.2654f8d1261a420f.woff2 +0 -0
  365. package/static/edgepress/fonts/noto-serif-latin-wght-normal.46281456234014ce.woff2 +0 -0
  366. package/static/edgepress/fonts/noto-serif-math-wght-normal.d4a6aba2cb4636b3.woff2 +0 -0
  367. package/static/edgepress/fonts/noto-serif-vietnamese-wght-normal.fb6a5ed734c2fbe3.woff2 +0 -0
  368. package/static/edgepress/fonts/provenance.json +1356 -0
  369. package/static/edgepress/fonts.css +14 -0
  370. package/static/edgepress/image-viewer.js +23 -0
  371. package/static/edgepress/images.css +4 -0
  372. package/static/edgepress/link-directory.css +14 -0
  373. package/static/edgepress/local-time.js +12 -0
  374. package/static/edgepress/media-viewer.css +1 -0
  375. package/static/edgepress/media-viewer.js +111 -0
  376. package/static/edgepress/navigation-select.js +14 -0
  377. package/static/edgepress/oembed.js +129 -0
  378. package/static/edgepress/plugins/backend/external-api.js +4 -0
  379. package/static/edgepress/plugins/backend/external-widget.js +13 -0
  380. package/static/edgepress/plugins/consent/choices.js +47 -0
  381. package/static/edgepress/plugins/consent/manager.js +56 -74
  382. package/static/edgepress/project-demo.js +93 -0
  383. package/static/edgepress/search.js +2 -2
  384. package/static/edgepress/services-consent.js +3 -0
  385. package/static/edgepress/services.js +15 -0
  386. package/static/edgepress/webmcp.js +86 -0
  387. package/tests/assets-runtime.test.mjs +91 -0
  388. package/tests/audit.test.mjs +142 -0
  389. package/tests/brand-regression.test.mjs +110 -0
  390. package/tests/consent-browser.test.mjs +132 -0
  391. package/tests/consent-config.test.mjs +85 -0
  392. package/tests/consent-csp.test.mjs +90 -0
  393. package/tests/data-saver-loading.test.mjs +158 -0
  394. package/tests/data-saver-network.test.mjs +99 -0
  395. package/tests/data-saver.test.mjs +294 -0
  396. package/tests/document-package.test.mjs +28 -0
  397. package/tests/document-viewer.test.mjs +152 -0
  398. package/tests/edge-issues.test.mjs +65 -0
  399. package/tests/embed-syntax.test.mjs +68 -0
  400. package/tests/external-links.test.mjs +198 -0
  401. package/tests/fixtures/recording.mp4 +0 -0
  402. package/tests/fonts.test.mjs +99 -0
  403. package/tests/image-dimensions.test.mjs +15 -0
  404. package/tests/image-viewer.test.mjs +36 -0
  405. package/tests/json-pages.test.mjs +66 -0
  406. package/tests/link-directory.test.mjs +51 -0
  407. package/tests/local-tool.test.mjs +34 -0
  408. package/tests/markdown-media.test.mjs +119 -0
  409. package/tests/media-block.test.mjs +102 -0
  410. package/tests/navigation.test.mjs +87 -0
  411. package/tests/oembed-layout.test.mjs +98 -0
  412. package/tests/oembed.test.mjs +96 -0
  413. package/tests/page-authoring.test.mjs +27 -0
  414. package/tests/page-formatting.test.mjs +37 -0
  415. package/tests/post-list.test.mjs +96 -0
  416. package/tests/project-demo.test.mjs +73 -0
  417. package/tests/publication-time.test.mjs +43 -0
  418. package/tests/release-version.test.mjs +28 -0
  419. package/tests/revisions.test.mjs +93 -0
  420. package/tests/rss.test.mjs +54 -0
  421. package/tests/services.test.mjs +35 -0
  422. package/tests/theme-layout.test.mjs +95 -0
  423. package/tests/video-metadata.test.mjs +28 -0
  424. package/tests/webmcp.test.mjs +121 -0
  425. package/tests/writing.test.mjs +101 -0
  426. package/themes/atelier/assets/style.css +144 -22
  427. package/themes/atelier/layouts/partials/head.html +8 -1
  428. package/themes/atelier/layouts/partials/header.html +3 -1
  429. package/themes/default/assets/data-saver-theme.css +2 -0
  430. package/themes/default/assets/style.css +139 -23
  431. package/themes/default/layouts/partials/head.html +9 -2
  432. package/themes/default/layouts/partials/header.html +3 -1
  433. package/themes/default/theme.json +1 -0
  434. package/themes/folio/README.md +7 -0
  435. package/themes/folio/assets/data-saver-theme.css +3 -0
  436. package/themes/folio/assets/folio/navigation.js +10 -0
  437. package/themes/folio/assets/style.css +516 -0
  438. package/themes/folio/layouts/layout.html +15 -0
  439. package/themes/folio/layouts/partials/footer.html +6 -0
  440. package/themes/folio/layouts/partials/head.html +30 -0
  441. package/themes/folio/layouts/partials/header.html +8 -0
  442. package/themes/folio/theme.json +7 -0
  443. package/themes/signal/assets/style.css +143 -21
  444. package/themes/signal/layouts/partials/head.html +8 -1
  445. package/themes/signal/layouts/partials/header.html +3 -1
  446. package/tools/README.md +14 -0
  447. package/tools/assets/format-pages.mjs +56 -0
  448. package/tools/assets/generate-brand-assets.py +160 -0
  449. package/tools/assets/sync-fonts.mjs +71 -0
  450. package/tools/assets/sync-icons.mjs +17 -0
  451. package/tools/assets/video-preview.mjs +15 -0
  452. package/tools/recordings/capture-document-demo.mjs +147 -0
  453. package/tools/recordings/demo-workbench.mjs +57 -0
  454. package/tools/recordings/desktop-recording.mjs +92 -0
  455. package/tools/recordings/provision-vm.sh +18 -0
  456. package/tools/recordings/start-vm-desktop.sh +28 -0
  457. package/tools/recordings/vm-desktop.mjs +124 -0
  458. package/tools/verification/README.md +44 -0
  459. package/tools/verification/data-saver-site.mjs +405 -0
  460. package/tools/verification/page-performance.mjs +76 -0
  461. package/tools/verification/verify-brand-assets.py +52 -0
  462. package/tools/verification/verify-brand.mjs +180 -0
  463. package/vercel.json +36 -0
  464. package/wrangler.jsonc +5 -7
  465. package/content/pages/home/en.md +0 -99
  466. package/content/pages/home/zh-cn.md +0 -99
  467. package/content/pages/plugin-development/en.md +0 -109
  468. package/content/pages/plugin-development/zh-cn.md +0 -109
  469. package/content/pages/privacy-policy/en.md +0 -93
  470. package/content/pages/privacy-policy/zh-cn.md +0 -93
  471. package/content/pages/project-introduction/en.md +0 -88
  472. package/content/pages/project-introduction/zh-cn.md +0 -88
  473. package/content/pages/quick-start/en.md +0 -153
  474. package/content/pages/quick-start/zh-cn.md +0 -153
  475. package/content/pages/theme-development/en.md +0 -132
  476. package/content/pages/theme-development/zh-cn.md +0 -132
  477. package/src/worker.js +0 -139
  478. package/static/edgepress/brand/edgepress-mark.svg +0 -7
  479. package/static/edgepress/brand/mascot-209.webp +0 -0
  480. package/static/edgepress/brand/mascot-418.png +0 -0
  481. package/static/edgepress/brand/mascot-418.webp +0 -0
  482. package/static/edgepress/brand/mascot.png +0 -0
  483. package/static/edgepress/brand/og-image.png +0 -0
  484. package/static/edgepress/brand/og-image.svg +0 -46
  485. package/static/edgepress/icons.svg +0 -24
@@ -1,4 +1,4 @@
1
- :root{color-scheme:light;--paper:#fbfaf7;--ink:#222722;--muted:#667168;--line:#dfe4dc;--accent:#426b57;font:16px/1.75 ui-sans-serif,system-ui,-apple-system,"Segoe UI",sans-serif}*{box-sizing:border-box}body{max-width:920px;margin:0 auto;padding:0 28px;background:var(--paper);color:var(--ink)}a{color:var(--accent);text-underline-offset:.18em}a:hover{text-decoration-thickness:2px}.skip-link{position:absolute;left:-10000px;top:auto}.skip-link:focus{left:16px;top:16px;padding:10px 14px;background:#fff;border:2px solid var(--accent);z-index:2}.site-header{display:flex;align-items:center;justify-content:space-between;gap:24px;padding:28px 0;border-bottom:1px solid var(--line)}.brand{font-size:1.3rem;font-weight:750;color:var(--ink);text-decoration:none}.site-header nav,.locale-nav{display:flex;flex-wrap:wrap;gap:18px}.site-header nav a{text-decoration:none}main{min-height:64vh;padding:38px 0}.intro{max-width:680px;margin-bottom:36px}.intro h1,.post h1,.page h1,main>section>h1{font-size:clamp(2rem,6vw,3.25rem);letter-spacing:-.035em;line-height:1.12}.post-card{padding:18px 0;border-top:1px solid var(--line)}.post-card h2{margin:0;font-size:1.35rem}.meta,.tags,footer{color:var(--muted)}.meta{font-size:.9rem}.post-content img{max-width:100%;height:auto}.post-content pre{overflow:auto;padding:16px;background:#edf0ea;border-radius:8px}.post-content code{font-family:ui-monospace,SFMono-Regular,Consolas,monospace}.post-content table{display:block;max-width:100%;overflow:auto;border-collapse:collapse}.post-content th,.post-content td{padding:8px 12px;border:1px solid var(--line)}.pagination{display:flex;justify-content:space-between;margin-top:30px}.locale-nav{justify-content:flex-end;padding-top:12px;font-size:.88rem}.locale-nav a{color:var(--muted)}a:focus-visible{outline:3px solid #cb774d;outline-offset:3px}footer{border-top:1px solid var(--line);padding:24px 0;font-size:.9rem}@media(max-width:620px){body{padding:0 17px}.site-header{align-items:flex-start;flex-direction:column;gap:14px}.site-header nav{gap:14px}.locale-nav{justify-content:flex-start}}
1
+ :root{color-scheme:light;--paper:#fbfaf7;--ink:#222722;--muted:#667168;--line:#dfe4dc;--accent:#426b57;font:16px/1.75 var(--edgepress-font-sans)}*{box-sizing:border-box}body{max-width:920px;margin:0 auto;padding:0 28px;background:var(--paper);color:var(--ink)}a{color:var(--accent);text-underline-offset:.18em}a:hover{text-decoration-thickness:2px}.skip-link{position:absolute;left:-10000px;top:auto}.skip-link:focus{left:16px;top:16px;padding:10px 14px;background:#fff;border:2px solid var(--accent);z-index:2}.site-header{display:flex;align-items:center;justify-content:space-between;gap:24px;padding:28px 0;border-bottom:1px solid var(--line)}.brand{font-size:1.3rem;font-weight:750;color:var(--ink);text-decoration:none}.site-header nav,.locale-nav{display:flex;flex-wrap:wrap;gap:18px}.site-header nav a{text-decoration:none}main{min-height:64vh;padding:38px 0}.intro{max-width:680px;margin-bottom:36px}.intro h1,.post h1,.page h1,main>section>h1{font-size:clamp(2rem,6vw,3.25rem);letter-spacing:-.035em;line-height:1.12}.post-card{padding:18px 0;border-top:1px solid var(--line)}.post-card h2{margin:0;font-size:1.35rem}.meta,.tags,footer{color:var(--muted)}.meta{font-size:.9rem}.post-content img{max-width:100%;height:auto}.post-content pre{overflow:auto;padding:16px;background:#edf0ea;border-radius:8px}.post-content code{font-family:var(--edgepress-font-mono)}.post-content table{display:block;max-width:100%;overflow:auto;border-collapse:collapse}.post-content th,.post-content td{padding:8px 12px;border:1px solid var(--line)}.pagination{display:flex;justify-content:space-between;margin-top:30px}.locale-nav{justify-content:flex-end;padding-top:12px;font-size:.88rem}.locale-nav a{color:var(--muted)}a:focus-visible{outline:3px solid #cb774d;outline-offset:3px}footer{border-top:1px solid var(--line);padding:24px 0;font-size:.9rem}@media(max-width:620px){body{padding:0 17px}.site-header{align-items:flex-start;flex-direction:column;gap:14px}.site-header nav{gap:14px}.locale-nav{justify-content:flex-start}}
2
2
 
3
3
  /* Page flow keeps the footer at the viewport bottom on short pages. */
4
4
  body{display:flex;flex-direction:column;min-height:100vh}
@@ -16,9 +16,9 @@ main{flex:1;min-height:0}
16
16
  .image-block figcaption,.quote-block figcaption{color:var(--muted);font-size:.9rem}
17
17
  .faq-block details{margin:12px 0}.faq-block summary{cursor:pointer;font-weight:700}
18
18
  .ad-slot:empty{min-height:90px}.captcha-block{min-height:65px}
19
-
20
19
 
21
- .privacy-manager{position:fixed;inset-inline-end:max(12px,env(safe-area-inset-right));inset-block-end:max(12px,env(safe-area-inset-bottom));z-index:1000;display:grid;align-content:end;gap:7px;box-sizing:border-box;width:min(28rem,calc(100vw - 24px));max-height:calc(100dvh - 24px);color:var(--ink,#1d2824);font:14px/1.45 ui-sans-serif,system-ui,sans-serif;pointer-events:none;isolation:isolate}
20
+
21
+ .privacy-manager{position:fixed;inset-inline-end:max(12px,env(safe-area-inset-right));inset-block-end:max(12px,env(safe-area-inset-bottom));z-index:1000;display:grid;align-content:end;gap:7px;box-sizing:border-box;width:min(28rem,calc(100vw - 24px));max-height:calc(100dvh - 24px);color:var(--ink,#1d2824);font:14px/1.45 var(--edgepress-font-sans);pointer-events:none;isolation:isolate}
22
22
  .privacy-manager *{box-sizing:border-box}
23
23
  .privacy-manager>*{min-width:0;pointer-events:auto}
24
24
  .privacy-manager .privacy-settings-button,.privacy-manager .privacy-panel button{display:inline-flex;justify-content:center;align-items:center;gap:8px;min-width:0;min-height:44px;max-width:100%;padding:9px 13px;border:1px solid var(--line,#c7d0c9);border-radius:999px;background:var(--paper,#fff);color:var(--ink,#1d2824);font:inherit;font-weight:700;line-height:1.25;text-align:center;overflow-wrap:anywhere;cursor:pointer}
@@ -28,8 +28,8 @@ main{flex:1;min-height:0}
28
28
  .privacy-manager .privacy-panel h2{margin:0;padding-inline-end:44px;font-size:1.08rem;line-height:1.3}
29
29
  .privacy-manager .privacy-panel p{margin:0;overflow-wrap:anywhere}
30
30
  .privacy-manager .privacy-panel .privacy-close{position:absolute;inset-block-start:6px;inset-inline-end:6px;width:44px;min-width:44px;min-height:44px;padding:8px;border-radius:50%}
31
- .privacy-manager .privacy-panel .privacy-close svg{width:20px;height:20px}
32
- .privacy-manager svg{width:18px;height:18px;flex:none}
31
+ .privacy-manager .privacy-panel .privacy-close .icon-library{width:20px;height:20px}
32
+ .privacy-manager .icon-library{width:18px;height:18px;flex:none}
33
33
  .privacy-manager .privacy-intro,.privacy-manager .privacy-essential,.privacy-manager .privacy-controller{color:var(--muted,#536159)}
34
34
  .privacy-manager .privacy-service-settings{display:grid;gap:7px;min-width:0}
35
35
  .privacy-manager .privacy-service-setting{display:grid;gap:5px;min-width:0;padding:10px;border:1px solid var(--line,#c7d0c9);border-radius:10px;background:var(--panel,#fff)}
@@ -42,7 +42,6 @@ main{flex:1;min-height:0}
42
42
  .privacy-manager .privacy-service-toggle-text{grid-column:1;grid-row:1;display:grid;gap:3px;min-width:0;overflow-wrap:anywhere}
43
43
  .privacy-manager .privacy-service-toggle-text strong{font-size:.94rem}
44
44
  .privacy-manager .privacy-service-purpose{color:var(--muted,#536159);font-size:.86rem;line-height:1.4}
45
- .privacy-manager .privacy-category{justify-self:start;max-width:100%;padding:1px 7px;border-radius:999px;background:color-mix(in srgb,var(--accent,#315e49) 12%,transparent);color:var(--ink,#1d2824);font-size:.74rem;overflow-wrap:anywhere}
46
45
  .privacy-manager .privacy-details{min-width:0;margin:0;border-top:1px solid var(--line,#c7d0c9)}
47
46
  .privacy-manager .privacy-details>summary{padding:7px 1px 0;font-size:.86rem;font-weight:700;cursor:pointer}
48
47
  .privacy-manager .privacy-details>summary:focus-visible{outline:3px solid var(--accent,#315e49);outline-offset:3px}
@@ -62,7 +61,7 @@ main{flex:1;min-height:0}
62
61
  .privacy-manager .privacy-policy-link{width:fit-content;max-width:100%;font-size:.86rem}
63
62
  .privacy-manager .privacy-policy-link:focus-visible,.privacy-manager .privacy-settings-button:focus-visible,.privacy-manager .privacy-panel button:focus-visible{outline:3px solid var(--accent,#315e49);outline-offset:3px}
64
63
  .privacy-manager .privacy-empty{padding:9px;border:1px dashed var(--line,#c7d0c9);border-radius:8px;color:var(--muted,#536159)}
65
- @media(max-width:560px){.privacy-manager{inset-inline-start:max(12px,env(safe-area-inset-left));width:auto;max-width:none}.privacy-manager .privacy-panel{max-height:min(66vh,40rem);max-height:min(66dvh,40rem);padding:13px}.privacy-manager .privacy-actions{gap:6px}}
64
+ @media(max-width:560px){.privacy-manager{inset-inline-start:max(12px,env(safe-area-inset-left));width:auto;max-width:none}.privacy-manager .privacy-panel{max-height:min(66vh,40rem);max-height:min(66dvh,40rem);padding:13px}.privacy-manager .privacy-actions{gap:6px}}
66
65
  /* Page blocks follow a section-and-widget layout, while articles keep their own reading column. */
67
66
  body{max-width:none;padding:0 clamp(18px,4vw,56px)}
68
67
  .site-header,main,.site-footer{width:min(100%,1240px);margin-inline:auto}
@@ -98,7 +97,7 @@ main{padding:clamp(32px,5vw,64px) 0}
98
97
  .steps-widget li{counter-increment:step}
99
98
  .steps-widget li::before{content:counter(step,decimal-leading-zero);display:block;color:var(--accent);font-size:.85rem;font-weight:800;letter-spacing:.08em;margin-bottom:8px}
100
99
  .steps-widget pre,.code-widget pre{overflow:auto;padding:16px;background:#202722;color:#f7f7f2;border-radius:10px}
101
- .steps-widget code,.code-widget code{font: .9rem/1.6 ui-monospace,SFMono-Regular,Consolas,monospace;white-space:pre}
100
+ .steps-widget code,.code-widget code{font: .9rem/1.6 var(--edgepress-font-mono);white-space:pre}
102
101
  .code-widget{margin:14px 0}
103
102
  .code-widget figcaption{font-size:.9rem;font-weight:700;margin:0 0 8px}
104
103
  .table-widget{overflow-x:auto;margin:18px 0}
@@ -120,7 +119,7 @@ main{padding:clamp(32px,5vw,64px) 0}
120
119
  .footer-navigation{display:flex;flex-direction:row;gap:18px}
121
120
  .error-page{max-width:760px;margin:8vh auto;text-align:center;padding:clamp(28px,6vw,72px);border:1px solid var(--line);border-radius:18px;background:#f0f2ed}
122
121
  .error-code{margin:0;color:var(--accent);font-size:clamp(4rem,14vw,9rem);font-weight:800;line-height:1;letter-spacing:-.08em}
123
-
122
+
124
123
 
125
124
  /* Page files define row column counts and then element types inside each column. */
126
125
  .page-builder-row{display:grid;gap:clamp(16px,2.5vw,30px);align-items:start}
@@ -131,8 +130,8 @@ main{padding:clamp(32px,5vw,64px) 0}
131
130
  .page-builder-cell{min-width:0}
132
131
  .page-builder-cell>.hero-block,.page-builder-cell>.page-section,.page-builder-cell>.feature-section,.page-builder-cell>.cta-block,.page-builder-cell>.faq-block,.page-builder-cell>.latest-posts{margin:0}
133
132
  .display-text{font-size:clamp(1.8rem,5vw,4rem);line-height:1.08;letter-spacing:-.045em}
134
- .display-text--serif{font-family:Georgia,"Iowan Old Style",serif;font-weight:500}
135
- .display-text--mono{font-family:ui-monospace,SFMono-Regular,Consolas,monospace;letter-spacing:-.06em}
133
+ .display-text--serif{font-family:var(--edgepress-font-serif);font-weight:500}
134
+ .display-text--mono{font-family:var(--edgepress-font-mono);letter-spacing:-.06em}
136
135
  .display-text--accent{color:var(--accent)}
137
136
  .display-text--outline{-webkit-text-stroke:1px currentColor;color:transparent}
138
137
  .media-text-block{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);align-items:center;gap:clamp(20px,4vw,48px)}
@@ -145,17 +144,17 @@ main{padding:clamp(32px,5vw,64px) 0}
145
144
  .privacy-controller-inline{display:flex;flex-wrap:wrap;align-items:baseline;gap:3px 10px;margin:0}
146
145
  .privacy-controller-inline span{min-width:0;overflow-wrap:anywhere}
147
146
  .privacy-controller-separator{color:var(--muted)}
148
- .privacy-vendor-link{display:inline-block;margin-block-start:4px}
147
+ .privacy-vendor-link{display:inline-block;margin-block-start:4px}
149
148
  .privacy-controller-details{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,210px),1fr));gap:12px}
150
149
  .privacy-controller-details>div{padding:14px;border:1px solid var(--line);border-radius:10px}
151
150
  .privacy-controller-details dt{font-size:.85rem;color:var(--muted);font-weight:700}
152
151
  .privacy-controller-details dd{margin:4px 0 0;overflow-wrap:anywhere}
153
- @media(max-width:760px){.page-builder-row[data-columns="2"],.page-builder-row[data-columns="3"],.page-builder-row[data-columns="4"]{grid-template-columns:minmax(0,1fr)}.media-text-block{grid-template-columns:1fr}.media-text-block--right figure{order:0}}
152
+ @media(max-width:760px){.page-builder-row[data-columns="2"],.page-builder-row[data-columns="3"],.page-builder-row[data-columns="4"]{grid-template-columns:minmax(0,1fr)}.media-text-block{grid-template-columns:1fr}.media-text-block--right figure{order:0}}
154
153
 
155
154
  .page-builder,.page-builder-row,.page-builder-cell,.hero-block,.hero-main,.hero-highlights{min-width:0}
156
155
  .page-builder-row{width:100%}
157
156
  .media-text-block,.media-text-block>*{min-width:0}
158
- @media(max-width:760px){html,body{max-width:100%}.site-header,main,.site-footer{max-width:100%;min-width:0}.hero-block{grid-template-columns:minmax(0,1fr)}.hero-highlights{grid-template-columns:minmax(0,1fr)}}
157
+ @media(max-width:760px){html,body{max-width:100%}.site-header,main,.site-footer{max-width:100%;min-width:0}.hero-block{grid-template-columns:minmax(0,1fr)}.hero-highlights{grid-template-columns:minmax(0,1fr)}}
159
158
 
160
159
  /* Keep long article content and generated page widgets inside narrow viewports. */
161
160
  html,body{width:100%;min-width:0;max-width:100%}
@@ -181,32 +180,32 @@ main,.page-builder,.page-builder-row,.page-builder-cell,.post,.post-content,.pos
181
180
  .local-search-results time{display:block;color:var(--muted);font-size:.9rem;margin-top:4px}
182
181
  .local-search-results p{margin:8px 0 0}
183
182
  .markdown-task-status{display:inline-block;min-width:1.35em;font-weight:800}
184
- @media(max-width:620px){.local-search-controls{align-items:stretch;flex-direction:column}.local-search-controls button{min-height:44px}.post-content pre,.code-widget pre,.steps-widget pre{padding:12px}}
183
+ @media(max-width:620px){.local-search-controls{align-items:stretch;flex-direction:column}.local-search-controls button{min-height:44px}.post-content pre,.code-widget pre,.steps-widget pre{padding:12px}}
185
184
  .locale-nav select{max-width:min(100%,13rem);padding:7px 30px 7px 10px;border:1px solid var(--line);border-radius:8px;background:var(--paper);color:var(--ink);font:inherit;cursor:pointer}
186
185
  .locale-nav select:focus-visible{outline:3px solid #cb774d;outline-offset:3px}
187
186
  @media(max-width:620px){.locale-nav select{min-height:42px;max-width:100%}}
188
187
 
189
188
  /* Article contents and code tools use theme styling and wrap on narrow screens. */
190
- .post-toc-widget{position:fixed;inset-inline-end:max(12px,env(safe-area-inset-right));inset-block-start:50%;z-index:950;max-width:calc(100vw - 24px);transform:translateY(-50%);color:var(--ink);font:14px/1.5 ui-sans-serif,system-ui,sans-serif}
189
+ .post-toc-widget{position:fixed;inset-inline-end:max(12px,env(safe-area-inset-right));inset-block-start:50%;z-index:950;max-width:calc(100vw - 24px);transform:translateY(-50%);color:var(--ink);font:14px/1.5 var(--edgepress-font-sans)}
191
190
  .post-toc-widget[hidden]{display:none}
192
191
  .post-toc-toggle{display:inline-flex;align-items:center;gap:7px;min-height:44px;padding:9px 12px;border:1px solid var(--line);border-radius:999px;background:var(--paper);color:var(--ink);font:inherit;font-weight:700;box-shadow:0 4px 18px #0002;cursor:pointer}
193
- .post-toc-toggle svg{width:18px;height:18px;flex:none}
192
+ .post-toc-toggle .icon-library{width:18px;height:18px;flex:none}
194
193
  .post-toc-toggle:focus-visible,.post-toc-close:focus-visible{outline:3px solid var(--accent);outline-offset:3px}
195
194
  .post-toc-panel{position:absolute;inset-inline-end:0;inset-block-end:calc(100% + 8px);display:grid;gap:8px;width:min(22rem,calc(100vw - 24px));max-height:min(60vh,32rem);overflow:auto;overscroll-behavior:contain;padding:14px;border:1px solid var(--line);border-radius:12px;background:var(--paper);box-shadow:0 12px 36px #0003}
196
195
  .post-toc-panel[hidden]{display:none}
197
196
  .post-toc-heading{display:flex;align-items:center;justify-content:space-between;gap:8px}
198
197
  .post-toc-heading h2{margin:0;font-size:1rem;letter-spacing:0}
199
198
  .post-toc-close{display:grid;place-items:center;width:40px;height:40px;flex:none;border:1px solid var(--line);border-radius:50%;background:var(--paper);color:var(--ink);font:inherit;font-size:1.35rem;line-height:1;cursor:pointer}
200
- .post-toc-panel ol{margin:0;padding-inline-start:1.25rem}
199
+ .post-toc-panel ol{margin:0;padding-inline-start:0;list-style:none}
201
200
  .post-toc-panel li{padding:3px 0;overflow-wrap:anywhere}
202
201
  .post-toc-panel .post-toc-level-3{padding-inline-start:1rem}
203
202
  .post-toc-panel .post-toc-level-4,.post-toc-panel .post-toc-level-5,.post-toc-panel .post-toc-level-6{padding-inline-start:2rem}
204
- @media(max-width:620px){.post-toc-widget{inset-inline-start:max(12px,env(safe-area-inset-left));inset-inline-end:auto;inset-block-start:auto;inset-block-end:max(12px,env(safe-area-inset-bottom));transform:none}.post-toc-panel{inset-inline-start:0;inset-inline-end:auto;max-height:min(58vh,30rem)}.post-toc-toggle{min-height:44px}}
203
+ @media(max-width:620px){.post-toc-widget{inset-inline-start:max(12px,env(safe-area-inset-left));inset-inline-end:auto;inset-block-start:auto;inset-block-end:max(12px,env(safe-area-inset-bottom));transform:none}.post-toc-panel{inset-inline-start:0;inset-inline-end:auto;max-height:min(58vh,30rem)}.post-toc-toggle{min-height:44px}}
205
204
  .post-content h2[id],.post-content h3[id],.post-content h4[id],.post-content h5[id],.post-content h6[id]{scroll-margin-top:1rem}
206
205
  .code-copy-block{max-width:100%;margin:1.25em 0;border-radius:10px;overflow:hidden;background:#edf0ea}
207
206
  .code-copy-block pre{margin:0;border-radius:0}
208
207
  .code-copy-toolbar{display:flex;justify-content:flex-end;padding:7px 10px;background:var(--ink)}
209
- .code-copy-button{min-height:36px;padding:5px 12px;border:1px solid currentColor;border-radius:7px;background:transparent;color:var(--paper);font:600 .88rem/1.3 ui-sans-serif,system-ui,sans-serif;cursor:pointer}
208
+ .code-copy-button{min-height:36px;padding:5px 12px;border:1px solid currentColor;border-radius:7px;background:transparent;color:var(--paper);font:600 .88rem/1.3 var(--edgepress-font-sans);cursor:pointer}
210
209
  .code-copy-button:hover{background:var(--accent)}
211
210
  .code-copy-button:focus-visible{outline:3px solid #cb774d;outline-offset:2px}
212
211
  .code-copy-status{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
@@ -231,15 +230,15 @@ body{background:radial-gradient(ellipse at 92% 0%,#e9e9ff 0,transparent 33%),var
231
230
  .code-copy-block pre{background:#211d49;color:#f7f8ff}
232
231
  .code-copy-button:focus-visible,.local-search-form :focus-visible{outline-color:var(--warm)}
233
232
 
234
- /* Shared EdgePress marks and SVG icons keep common navigation recognizable across themes. */
233
+ /* Shared EdgePress marks and bitmap icons keep common navigation recognizable across themes. */
235
234
  .brand{display:inline-flex;align-items:center;gap:10px}
236
235
  .brand-mark{display:block;width:36px;height:36px;flex:0 0 auto;object-fit:contain}
237
236
  .primary-navigation a,.site-header nav a,.footer-navigation a{display:inline-flex;align-items:center;gap:.42em}
238
- .navigation-icon{display:block;width:1.05em;height:1.05em;flex:0 0 auto;fill:none;stroke:currentColor;stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round}
237
+ .navigation-icon{display:block;width:1.05em;height:1.05em;flex:0 0 auto;}
239
238
  .hero-aside{display:grid;align-content:center;justify-items:center;gap:16px;min-width:0}
240
239
  .hero-mascot{display:block;width:min(100%,230px);height:auto;max-height:220px;object-fit:contain;filter:drop-shadow(0 9px 13px #315e4922)}
241
240
  .hero-aside .hero-highlights{width:100%;align-self:stretch}
242
- .feature-icon{display:block;width:34px;height:34px;margin:0 0 10px;color:var(--accent);fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
241
+ .feature-icon{display:block;width:34px;height:34px;margin:0 0 10px;color:var(--accent);}
243
242
  .latest-posts-pagination{justify-content:flex-start;gap:16px;margin-top:18px}
244
243
  .latest-posts-pagination a:last-child{margin-left:auto}
245
244
  .hero-mascot-picture{display:block;width:min(100%,230px)}
@@ -254,3 +253,120 @@ body{background:radial-gradient(ellipse at 92% 0%,#e9e9ff 0,transparent 33%),var
254
253
  .post-tags ul{display:flex;flex-wrap:wrap;gap:8px;margin:0;padding:0;list-style:none}
255
254
  .post-tags a{display:inline-block;padding:2px 10px;border:1px solid var(--line);border-radius:999px;background:var(--paper);color:var(--accent);font-weight:600;text-decoration:none}
256
255
  .post-tags a:hover{background:var(--line)}
256
+
257
+ /* Raster artwork and predictable spacing for generated page elements. */
258
+ .icon-library{display:inline-block;width:24px;height:24px;flex:none;object-fit:contain;vertical-align:middle}
259
+ .navigation-icon{width:20px;height:20px}
260
+ .feature-icon{width:32px;height:32px}
261
+ .post-toc-toggle .icon-library,.privacy-manager .icon-library{width:20px;height:20px}
262
+ .privacy-manager .privacy-accept .icon-library,.privacy-manager .privacy-reject .icon-library{filter:brightness(0) invert(1)}
263
+ .page-builder-cell{display:grid;align-content:start;gap:clamp(16px,2.5vw,28px)}
264
+ .page-builder-cell>*,.section-inner>*{min-width:0;margin-block:0}
265
+ .section-inner{display:grid;gap:16px}
266
+ .post-list{display:grid;gap:clamp(16px,2.5vw,24px)}
267
+ .archive-post-list{margin-block:24px}
268
+ .post-list>.post-card{margin:0}
269
+ .post-card .meta{margin-block:8px;line-height:1.6}
270
+ .latest-posts>h2,.feature-section>h2{margin-block:0 16px}
271
+ .pagination:not(.latest-posts-pagination){align-items:center;justify-content:center;gap:12px}
272
+ .pagination-pages{display:flex;align-items:center;justify-content:center;flex-wrap:wrap;gap:6px;margin:0;padding:0;list-style:none}
273
+ .pagination-pages a,.pagination-current{display:inline-flex;align-items:center;justify-content:center;min-width:44px;min-height:44px;padding:8px 12px;border:1px solid var(--line);border-radius:10px;background:var(--panel,var(--paper,var(--surface)));color:var(--ink);font-weight:600;text-decoration:none}
274
+ .pagination-current{border-color:var(--accent);box-shadow:inset 0 0 0 1px var(--accent);font-weight:800}
275
+ .pagination-ellipsis{padding-inline:4px;color:var(--muted)}
276
+ .hero-block--banner{grid-template-columns:minmax(0,1fr);gap:24px}
277
+ .hero-banner{display:block;width:min(100%,680px);height:auto;max-height:460px;margin:0 auto;object-fit:contain}
278
+ .hero-block--banner .hero-aside{max-width:100%}
279
+
280
+ .page-section--dark .icon-library{filter:brightness(0) invert(1)}
281
+
282
+ .brand-mark{width:36px;height:36px;object-fit:contain;border-radius:50%;background:#f8efdc;padding:2px}
283
+ .hero-mascot,.hero-mascot-picture{width:min(100%,320px);max-height:240px}
284
+ .hero-banner-picture{display:block;margin-top:24px}
285
+
286
+ /* Journal metadata and accessible project navigation. */
287
+ .navigation-select[hidden] { display: none; }
288
+ .navigation-select { display: inline-flex; align-items: center; gap: .42em; max-width: 100%; color: var(--accent); }
289
+ .navigation-select select { font: inherit; color: inherit; background: transparent; border: 0; border-radius: 0; padding: .25rem 0; min-height: 44px; max-width: 100%; field-sizing: content; cursor: pointer; }
290
+ .primary-navigation a { min-height: 44px; }
291
+ .navigation-select option { color: CanvasText; background: Canvas; }
292
+ .navigation-select select:focus-visible { outline: 2px solid currentColor; outline-offset: 3px; }
293
+ .post-byline { display: flex; align-items: center; flex-wrap: wrap; gap: .7rem 1.2rem; margin-block: 1rem; }
294
+ .post-byline .post-author { display: inline-flex; align-items: center; gap: .55rem; }
295
+ .author-avatar { width: 40px; height: 40px; flex: 0 0 40px; border-radius: 50%; object-fit: cover; }
296
+ .post-tags { display: flex; align-items: center; flex-wrap: wrap; gap: .45rem; margin-block: 1rem 1.5rem; }
297
+ .post-tag { display: inline-block; max-width: 100%; overflow-wrap: anywhere; border: 1px solid currentColor; border-radius: 1rem; padding: .15rem .6rem; font-size: .85em; }
298
+
299
+ .post-changes{margin:1.5rem 0;border:1px solid var(--line);border-radius:12px;overflow:hidden;color:var(--ink)}
300
+ .post-changes summary{cursor:pointer;font-weight:650;padding:1rem;min-height:44px;background:var(--surface,var(--panel,var(--paper,transparent)))}
301
+ .post-changes summary:focus-visible{outline:3px solid var(--accent);outline-offset:-3px}
302
+ .post-changes-list{display:grid;gap:1rem;padding:1rem}
303
+ .post-change-passage{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,240px),1fr));gap:1rem}
304
+ .post-change-side{min-width:0;padding:1rem;border:1px solid var(--line);border-radius:10px;background:var(--surface,var(--panel,var(--paper,transparent)))}
305
+ .post-change-after{border-inline-start:4px solid var(--accent);background:color-mix(in srgb,var(--accent) 7%,transparent)}
306
+ .post-change-label{font-weight:650;margin:0 0 .75rem;font-size:.9rem;color:var(--muted,var(--ink))}
307
+ .post-change-content{overflow-wrap:anywhere;font-size:.95rem;line-height:1.7}
308
+ .post-change-content>:first-child{margin-top:0}.post-change-content>:last-child{margin-bottom:0}
309
+ .post-change-heading{font-weight:650;font-size:1.1rem;margin:.5rem 0}
310
+ .post-change-content img{max-width:100%;height:auto}.post-change-content pre{overflow:auto;white-space:pre-wrap;overflow-wrap:anywhere}
311
+
312
+ /* Media blocks inherit their page cell width, including mixed-column layouts. */
313
+
314
+ /* Align shared block geometry with Lumen while retaining this theme's palette. */
315
+ .site-header{display:block}
316
+ .header-inner{display:grid;grid-template-columns:minmax(0,1fr) auto auto;align-items:center;gap:18px;width:100%;min-width:0}
317
+ .header-inner>*{min-width:0}.brand{max-width:100%;overflow-wrap:anywhere}
318
+ .site-header .primary-navigation{align-items:center;justify-content:flex-end;column-gap:18px}
319
+ .locale-nav{padding:0}.locale-nav select{max-width:150px;min-height:44px}
320
+ .page-builder{display:grid;gap:clamp(24px,4vw,40px)}
321
+ .page-builder-row{align-items:stretch}
322
+ .page-builder-cell{display:grid;align-content:start;gap:clamp(16px,2.5vw,28px)}
323
+ .page-builder-cell>*{min-width:0;margin-block:0}
324
+ .image-block,.code-widget,.post-content figure{min-width:0;margin-inline:0}
325
+ .image-block img,.media-text-block img,.media-text-block video,.hero-mascot,.hero-banner{display:block;height:auto;max-height:none;max-width:100%;object-fit:contain}
326
+ .image-block figcaption,.media-text-block figcaption{font-size:.9rem;line-height:1.65;overflow-wrap:anywhere}
327
+ .hero-banner-picture,.hero-mascot-picture{display:block;min-width:0;max-width:100%}
328
+ .hero-block.hero-block--banner{display:grid;grid-template-columns:minmax(0,1fr);gap:24px}
329
+ .hero-banner-picture{margin-top:0}.hero-block--banner .hero-aside{max-width:100%}
330
+ .local-search-controls input{background:var(--paper,var(--panel));color:var(--ink)}
331
+ .site-footer{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:12px 24px}
332
+ .site-footer>p{margin:0}.footer-navigation{align-items:center}
333
+ .post-toc-widget{inset-inline-start:auto;inset-inline-end:max(12px,env(safe-area-inset-right));inset-block-start:auto;inset-block-end:calc(max(12px,env(safe-area-inset-bottom)) + 56px);transform:none}
334
+ .post-toc-panel{inset-inline-start:auto;inset-inline-end:0}
335
+ @media(max-width:880px){.header-inner{grid-template-columns:minmax(0,1fr) auto}.primary-navigation{grid-column:1/-1;grid-row:2}.site-header .primary-navigation{justify-content:flex-start}.locale-nav{grid-column:2;grid-row:1}.brand{font-size:1.15rem}.locale-nav select{max-width:125px}.page-builder-row[data-columns="3"],.page-builder-row[data-columns="4"]{grid-template-columns:repeat(2,minmax(0,1fr))}}
336
+ @media(max-width:760px){.page-builder-row[data-columns="2"],.page-builder-row[data-columns="3"],.page-builder-row[data-columns="4"]{grid-template-columns:minmax(0,1fr)}.site-header .primary-navigation{gap:6px 16px}.site-footer{align-items:flex-start;flex-direction:column}.hero-block{grid-template-columns:minmax(0,1fr)}}
337
+ @media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}*,*::before,*::after{transition-duration:.01ms!important;animation-duration:.01ms!important;animation-iteration-count:1!important}}
338
+
339
+ .post-content a{text-decoration:underline;text-underline-offset:.18em}.post-byline time{font-variant-numeric:tabular-nums}
340
+ @media(max-width:600px){.post-byline>time,.post-byline .post-updated{flex-basis:100%;min-width:0}.post-byline time[data-date-only="false"],.post-updated{min-block-size:3.2em;line-height:1.6}}
341
+
342
+ /* Embed consent, status and controls inherit the surrounding website palette. */
343
+ .edgepress-oembed{width:100%;min-width:0;margin:1.5rem 0;padding:clamp(14px,3vw,24px);border:1px solid var(--line);border-radius:16px;background:var(--surface,var(--panel,var(--paper,transparent)));color:var(--ink);overflow-wrap:anywhere}
344
+ .edgepress-oembed>figcaption{font:inherit;font-weight:650;margin:0 0 .75rem}
345
+ .edgepress-oembed [data-oembed-notice]{color:var(--muted,var(--ink));font-size:.9rem;line-height:1.6;margin:.5rem 0 1rem}
346
+ .edgepress-oembed [data-oembed-load]{appearance:none;font:inherit;font-weight:650;min-height:44px;padding:10px 18px;margin:0 12px 12px 0;border:1px solid var(--accent);border-radius:10px;background:var(--accent);color:var(--paper);cursor:pointer;transition:filter .15s,transform .15s}
347
+ .edgepress-oembed [data-oembed-load]:hover{filter:brightness(1.1);transform:translateY(-1px)}
348
+ .edgepress-oembed [data-oembed-load]:focus-visible{outline:3px solid var(--accent);outline-offset:3px}
349
+ .edgepress-oembed[aria-busy=true] [data-oembed-load]{pointer-events:none;opacity:.6}
350
+ .edgepress-oembed>a{display:inline-flex;align-items:center;min-height:44px;color:var(--accent);font-size:.9rem}
351
+ .edgepress-oembed [data-oembed-status],.oembed-content{min-width:0;max-width:100%}
352
+ .edgepress-oembed [data-oembed-status]{min-height:clamp(160px,calc((100vw - 48px)*.75),480px);position:relative}
353
+ .edgepress-oembed .oembed-placeholder{aspect-ratio:var(--oembed-ratio,4/3);min-height:160px;border-radius:10px;background:linear-gradient(110deg,color-mix(in srgb,var(--surface,var(--paper,#fff)) 78%,var(--accent) 22%),color-mix(in srgb,var(--surface,var(--paper,#fff)) 92%,var(--accent) 8%),color-mix(in srgb,var(--surface,var(--paper,#fff)) 78%,var(--accent) 22%));background-size:200% 100%}
354
+ .edgepress-oembed.is-loading .oembed-placeholder{animation:edgepress-oembed-shimmer 1.4s linear infinite}
355
+ .edgepress-oembed[data-loaded=true] [data-oembed-status]{min-height:0}.edgepress-oembed[data-loaded=true] .oembed-placeholder{display:none}
356
+ @keyframes edgepress-oembed-shimmer{to{background-position:-200% 0}}
357
+ .edgepress-oembed iframe,.edgepress-oembed img,.edgepress-oembed blockquote{max-width:100%;margin-inline:auto;border-radius:10px}
358
+ .edgepress-oembed[data-loaded=true]>[data-oembed-notice]{margin-bottom:.25rem}
359
+ .oembed-caption{white-space:pre-wrap}
360
+ .post-change-content img{display:block;width:100%;height:auto;max-height:420px;object-fit:contain;background:var(--surface,var(--panel,var(--paper,transparent)));border-radius:8px}
361
+ @media(prefers-reduced-motion:reduce){.edgepress-oembed [data-oembed-load]{transition:none}}
362
+ @media(prefers-reduced-motion:reduce){.edgepress-oembed.is-loading .oembed-placeholder{animation:none}}
363
+
364
+ .project-demo{position:relative;min-width:0}.project-demo img{display:block;width:100%;height:auto;border-radius:12px}.project-demo-media{position:relative}.project-demo-media video{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;border-radius:12px}.project-demo-media.is-ready img{visibility:hidden}.project-demo [hidden]{display:none!important}.project-demo button{display:inline-flex;align-items:center;justify-content:center;min-height:44px;margin-top:12px;padding:10px 18px;border:1px solid var(--accent);border-radius:999px;background:var(--surface,var(--panel,var(--paper,transparent)));color:var(--ink);font:inherit;font-weight:650;cursor:pointer}.project-demo button:focus-visible{outline:3px solid var(--accent);outline-offset:4px}.project-demo button:disabled{cursor:wait;opacity:.7}.project-demo-status{display:block;min-height:1.4em;color:var(--ink);font-size:.9rem;margin-top:6px}
365
+
366
+ .table-widget:focus-visible{outline:3px solid var(--accent);outline-offset:4px}
367
+
368
+ .project-demo-seek{display:block;width:100%;min-height:44px;margin:4px 0;accent-color:var(--accent);cursor:pointer}.project-demo-seek:focus-visible{outline:3px solid var(--accent);outline-offset:3px}.project-demo-time{display:block;font-variant-numeric:tabular-nums;color:var(--ink);line-height:1.5}.project-demo-seek:disabled{cursor:wait;opacity:.5}
369
+
370
+ /* Vertical touch gestures scroll the page; seeking requires horizontal intent. */
371
+ .project-demo-seek{touch-action:pan-y;user-select:none}
372
+ .edgepress-oembed:not([data-loaded=true]) [data-oembed-status]{min-height:0}.edgepress-oembed:not(.is-loading) .oembed-placeholder{display:none}.edgepress-oembed.is-loading .oembed-placeholder{height:3rem;min-height:0;aspect-ratio:auto}.edgepress-oembed [data-oembed-load]:disabled{cursor:wait;opacity:.6}.edgepress-oembed>figcaption a:focus-visible{outline:3px solid var(--accent);outline-offset:3px}
@@ -6,17 +6,24 @@
6
6
  <meta name="author" content="{{site.seo.author}}">
7
7
  <title>{{page.title}}</title>
8
8
  <meta name="theme-color" content="#315e49">
9
- <link rel="icon" type="image/svg+xml" href="/edgepress/brand/edgepress-mark.svg">
9
+ <link rel="icon" href="/edgepress/favicon/favicon.ico" sizes="any">
10
+ <link rel="icon" type="image/png" sizes="16x16" href="/edgepress/favicon/favicon-16.png">
11
+ <link rel="icon" type="image/png" sizes="32x32" href="/edgepress/favicon/favicon-32.png">
12
+ <link rel="icon" type="image/png" sizes="48x48" href="/edgepress/favicon/favicon-48.png">
13
+ <link rel="icon" type="image/png" sizes="64x64" href="/edgepress/favicon/favicon-64.png">
14
+ <link rel="apple-touch-icon" sizes="180x180" href="/edgepress/favicon/apple-touch-icon.png">
10
15
  <link rel="canonical" href="{{page.canonical}}">
11
16
  <meta property="og:type" content="website">
12
17
  <meta property="og:title" content="{{page.title}}">
13
18
  <meta property="og:description" content="{{page.description}}">
14
19
  <meta property="og:url" content="{{page.canonical}}">
15
20
  <meta property="og:image" content="{{page.image}}">
21
+ <meta property="og:image:alt" content="{{site.headerBrand}}">
16
22
  <meta name="twitter:card" content="summary_large_image">
17
23
  <meta name="twitter:title" content="{{page.title}}">
18
24
  <meta name="twitter:description" content="{{page.description}}">
19
25
  <meta name="twitter:image" content="{{page.image}}">
20
- <link rel="alternate" type="application/atom+xml" href="{{site.feedPath}}" title="{{site.feedLabel}}">
26
+ <meta name="twitter:image:alt" content="{{site.headerBrand}}">
27
+ <link rel="alternate" type="application/rss+xml" href="{{site.feedPath}}" title="{{site.feedLabel}}">
21
28
  <link rel="stylesheet" href="{{site.stylesheet}}">
22
29
  <script type="application/ld+json">{{{page.jsonLd}}}</script>
@@ -1,5 +1,7 @@
1
1
  <header class="site-header {{site.headerClass}}">
2
- <a class="brand {{site.brandClass}}" href="{{site.homePath}}"><img class="brand-mark" src="/edgepress/brand/edgepress-mark.svg" alt="" aria-hidden="true" width="36" height="36">{{site.headerBrand}}</a>
2
+ <div class="header-inner">
3
+ <a class="brand {{site.brandClass}}" href="{{site.homePath}}"><img class="brand-mark" src="/edgepress/brand/avatar.png" alt="" aria-hidden="true" width="36" height="36">{{site.headerBrand}}</a>
3
4
  <nav class="primary-navigation {{site.primaryNavigationClass}}" aria-label="{{site.mainNavigationLabel}}">{{{site.primaryNavigationHtml}}}</nav>
4
5
  <div class="locale-nav {{site.languageNavigationClass}}" role="group" aria-label="{{site.languageLabel}}">{{{site.localeLinksHtml}}}</div>
6
+ </div>
5
7
  </header>
@@ -1,5 +1,6 @@
1
1
  {
2
2
  "name": "default",
3
+ "dataSaver": { "stylesheet": "data-saver-theme.css", "scripts": [], "layoutStyles": ["style.css"] },
3
4
  "version": "1.0.0",
4
5
  "renderer": "layouts/layout.html",
5
6
  "templateEngine": "edgepress-partials-v1"
@@ -0,0 +1,7 @@
1
+ # Folio
2
+
3
+ An editorial magazine theme with serif headlines, a quiet monochrome palette, a wide masthead, thin rules and unboxed article grids. Its layout and built-in component coverage follow the existing JS.GRIPE Lumen theme.
4
+
5
+ Select `themes/folio` with the theme command in a source checkout. Dependency-based sites set `paths.theme` to `node_modules/edgepress/themes/folio` in `edgepress.config.mjs`, without a `theme` override in `config.yml`.
6
+
7
+ Page content stays in EdgePress blocks. A hero with `bannerSrc` or `bannerWebpSrcset` uses a text-and-image spread on desktop and stacks on mobile. A hero without media keeps a text layout. The theme supplies no cover images or placeholder content. Media keeps its original aspect ratio and captions remain below the image. Local fonts, local navigation JavaScript, keyboard focus, native search, consent controls and automatic light/dark appearance are supported.
@@ -0,0 +1,3 @@
1
+ html[data-edgepress-data-mode=text] .brand{font-family:Georgia,serif}html[data-edgepress-data-mode=text] .hero-block .edgepress-data-placeholder{display:none}html[data-edgepress-data-mode=text] .hero-block--banner{grid-template-columns:minmax(0,1fr)}html[data-edgepress-data-mode=text] .hero-block{min-height:0;padding-block:1rem}html[data-edgepress-data-mode=text] .hero-block h1{font-size:clamp(2rem,5vw,3.5rem)}html[data-edgepress-data-mode=text] .signal-cover:has(.edgepress-data-placeholder:not([data-loaded=true])),html[data-edgepress-data-mode=text] .signal-cover:has(.edgepress-data-placeholder:not([data-loaded=true]))+.signal-cover-credit{display:none}html[data-edgepress-data-mode=text] .post-card{box-shadow:none}html[data-edgepress-data-mode=text] .media-text-block{gap:1.5rem}
2
+ html[data-edgepress-data-mode=text] .signal-cover:has(.edgepress-data-placeholder:not([data-loaded=true]))+button,html[data-edgepress-data-mode=text] .signal-cover:has(.edgepress-data-placeholder:not([data-loaded=true]))~.signal-cover-credit{display:none}
3
+ html[data-edgepress-data-mode=text] .media-text-block:has(.edgepress-data-placeholder:not([data-loaded=true])){grid-template-columns:minmax(0,1fr);gap:1rem}html[data-edgepress-data-mode=text] .media-text-block:has(.edgepress-data-placeholder:not([data-loaded=true])) figure{order:2}
@@ -0,0 +1,10 @@
1
+ // Mark the current reading section without changing EdgePress navigation URLs.
2
+ const path = window.location.pathname;
3
+ for (const link of document.querySelectorAll('.primary-navigation a')) {
4
+ const destination = new URL(link.href, window.location.href);
5
+ if (destination.origin !== window.location.origin) continue;
6
+ if (destination.pathname === path ||
7
+ (document.querySelector('main .post') && destination.pathname.endsWith('/archives/'))) {
8
+ link.setAttribute('aria-current', 'page');
9
+ }
10
+ }