@hraness/design-kit 0.31.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 (345) hide show
  1. package/ARTICLE_COPY.md +208 -0
  2. package/HERO_FIELDS.md +55 -0
  3. package/ICONS.md +56 -0
  4. package/LANTERN_MATERIAL.md +60 -0
  5. package/LICENSE +21 -0
  6. package/MARKETING_COPY.md +49 -0
  7. package/MARKETING_PRESET.md +108 -0
  8. package/PALETTES.md +90 -0
  9. package/PAPER_THEME.md +128 -0
  10. package/README.md +745 -0
  11. package/STATUS_PAGES.md +67 -0
  12. package/STYLE.md +245 -0
  13. package/WRITING.md +72 -0
  14. package/dist/browser/index.js +2345 -0
  15. package/dist/chunk-44djxk16.js +6872 -0
  16. package/dist/chunk-5gtx3pza.js +9 -0
  17. package/dist/chunk-77391vmq.js +454 -0
  18. package/dist/chunk-7b1586eb.js +1209 -0
  19. package/dist/chunk-8834fh4n.js +6 -0
  20. package/dist/chunk-9t8xyqte.js +870 -0
  21. package/dist/chunk-cejpzyfh.js +446 -0
  22. package/dist/chunk-eh71jz57.js +429 -0
  23. package/dist/chunk-evb02bc1.js +516 -0
  24. package/dist/chunk-h4k7yv6x.js +368 -0
  25. package/dist/chunk-he8eznb1.js +760 -0
  26. package/dist/chunk-mr1vdcjq.js +404 -0
  27. package/dist/chunk-wzvdn8ey.js +116 -0
  28. package/dist/fonts/nebula-sans/social-fonts.generated.js +53 -0
  29. package/dist/icons.js +48 -0
  30. package/dist/index.js +237 -0
  31. package/dist/launch.js +41 -0
  32. package/dist/mockups/client.js +422 -0
  33. package/dist/mockups/index.js +1850 -0
  34. package/dist/portfolio.js +1549 -0
  35. package/dist/provider-marks.js +19 -0
  36. package/dist/react/charts.js +11 -0
  37. package/dist/react/hero-backdrop.js +8 -0
  38. package/dist/react/index.js +7252 -0
  39. package/dist/react/platform-install.js +10 -0
  40. package/dist/react/server.js +137 -0
  41. package/dist/stylex-manifest.json +1 -0
  42. package/dist/stylex.css +5392 -0
  43. package/dist/syntax-highlighting.js +15 -0
  44. package/dist/testing.js +250 -0
  45. package/package.json +377 -0
  46. package/portfolio-inventory.json +31 -0
  47. package/scripts/check-lantern-material-snapshot.d.mts +26 -0
  48. package/scripts/check-lantern-material-snapshot.mjs +126 -0
  49. package/scripts/check-marketing-snapshot.d.mts +12 -0
  50. package/scripts/check-marketing-snapshot.mjs +58 -0
  51. package/scripts/lantern-material-snapshot.ts +101 -0
  52. package/scripts/marketing-textures.ts +48 -0
  53. package/scripts/paper-theme-snapshot.ts +97 -0
  54. package/scripts/product-marketing-snapshot.ts +149 -0
  55. package/src/appearance-menu.css +266 -0
  56. package/src/appearance.ts +32 -0
  57. package/src/article-html.ts +269 -0
  58. package/src/article.ts +686 -0
  59. package/src/browser/appearance-menu.ts +604 -0
  60. package/src/browser/artifact-share.ts +164 -0
  61. package/src/browser/design-palette.ts +197 -0
  62. package/src/browser/foil.ts +124 -0
  63. package/src/browser/hero-light.ts +11 -0
  64. package/src/browser/index.ts +29 -0
  65. package/src/browser/status-field.ts +432 -0
  66. package/src/browser/status-page.ts +100 -0
  67. package/src/browser/sticky-offset.ts +82 -0
  68. package/src/browser/theme-color-sync.ts +213 -0
  69. package/src/charts.css +7 -0
  70. package/src/compiler-components.css +34 -0
  71. package/src/compiler-foundation.css +18 -0
  72. package/src/compiler-palettes.css +7 -0
  73. package/src/compiler-tokens.css +342 -0
  74. package/src/components.css +3 -0
  75. package/src/design-gallery.css +431 -0
  76. package/src/effects.css +14 -0
  77. package/src/fonts/geist-mono/GeistMono[wght].woff2 +0 -0
  78. package/src/fonts/geist-mono/OFL.txt +93 -0
  79. package/src/fonts/geist-mono/PROVENANCE.md +12 -0
  80. package/src/fonts/instrument-serif/OFL.txt +93 -0
  81. package/src/fonts/instrument-serif/UPSTREAM.md +14 -0
  82. package/src/fonts/instrument-serif/instrument-serif-latin-400.woff2 +0 -0
  83. package/src/fonts/nebula-sans/LICENSE.txt +96 -0
  84. package/src/fonts/nebula-sans/NebulaSans-Black.woff2 +0 -0
  85. package/src/fonts/nebula-sans/NebulaSans-BlackItalic.woff2 +0 -0
  86. package/src/fonts/nebula-sans/NebulaSans-Bold.otf +0 -0
  87. package/src/fonts/nebula-sans/NebulaSans-Bold.woff2 +0 -0
  88. package/src/fonts/nebula-sans/NebulaSans-BoldItalic.woff2 +0 -0
  89. package/src/fonts/nebula-sans/NebulaSans-Book.otf +0 -0
  90. package/src/fonts/nebula-sans/NebulaSans-Book.woff2 +0 -0
  91. package/src/fonts/nebula-sans/NebulaSans-BookItalic.woff2 +0 -0
  92. package/src/fonts/nebula-sans/NebulaSans-Light.woff2 +0 -0
  93. package/src/fonts/nebula-sans/NebulaSans-LightItalic.woff2 +0 -0
  94. package/src/fonts/nebula-sans/NebulaSans-Medium.woff2 +0 -0
  95. package/src/fonts/nebula-sans/NebulaSans-MediumItalic.woff2 +0 -0
  96. package/src/fonts/nebula-sans/NebulaSans-Semibold.woff2 +0 -0
  97. package/src/fonts/nebula-sans/NebulaSans-SemiboldItalic.woff2 +0 -0
  98. package/src/fonts/nebula-sans/PROVENANCE.md +14 -0
  99. package/src/fonts/nebula-sans/social-fonts.generated.ts +3873 -0
  100. package/src/fonts.css +106 -0
  101. package/src/icons/act60/act60.svg +5 -0
  102. package/src/icons/act60/application.svg +9 -0
  103. package/src/icons/act60/chapter-compare.svg +3 -0
  104. package/src/icons/act60/decree-residence.svg +6 -0
  105. package/src/icons/act60/estimate.svg +7 -0
  106. package/src/icons/act60/export-services.svg +4 -0
  107. package/src/icons/act60/investor.svg +13 -0
  108. package/src/icons/act60/presence.svg +7 -0
  109. package/src/icons/aicharts/aicharts.svg +6 -0
  110. package/src/icons/aicharts/cost-compare.svg +4 -0
  111. package/src/icons/aicharts/task-audio.svg +7 -0
  112. package/src/icons/aicharts/task-coding.svg +6 -0
  113. package/src/icons/aicharts/task-images.svg +3 -0
  114. package/src/icons/aicharts/task-reasoning.svg +9 -0
  115. package/src/icons/aicharts/task-research.svg +5 -0
  116. package/src/icons/aicharts/task-video.svg +4 -0
  117. package/src/icons/manifest.json +1371 -0
  118. package/src/icons/platonik/conversation.svg +3 -0
  119. package/src/icons/platonik/creature.svg +7 -0
  120. package/src/icons/platonik/economy.svg +4 -0
  121. package/src/icons/platonik/keep-light.svg +6 -0
  122. package/src/icons/platonik/platonik.svg +7 -0
  123. package/src/icons/platonik/spark-route.svg +15 -0
  124. package/src/icons/receipts/act60-retry.receipt.json +888 -0
  125. package/src/icons/receipts/act60.receipt.json +1366 -0
  126. package/src/icons/receipts/aicharts.receipt.json +1546 -0
  127. package/src/icons/receipts/platonik.receipt.json +1011 -0
  128. package/src/icons/receipts/roughday.receipt.json +770 -0
  129. package/src/icons/receipts/shared.receipt.json +1296 -0
  130. package/src/icons/receipts/slopcamera.receipt.json +1495 -0
  131. package/src/icons/receipts/soundfish-retry.receipt.json +460 -0
  132. package/src/icons/receipts/soundfish.receipt.json +1709 -0
  133. package/src/icons/receipts/sponge.receipt.json +1743 -0
  134. package/src/icons/receipts/stripe-history-retry.receipt.json +145 -0
  135. package/src/icons/receipts/stripe-history.receipt.json +1202 -0
  136. package/src/icons/receipts/wordcell.receipt.json +1924 -0
  137. package/src/icons/roughday/finance.svg +7 -0
  138. package/src/icons/roughday/roughday.svg +6 -0
  139. package/src/icons/roughday/technology.svg +4 -0
  140. package/src/icons/roughday/world.svg +4 -0
  141. package/src/icons/sets/act60.json +63 -0
  142. package/src/icons/sets/aicharts.json +63 -0
  143. package/src/icons/sets/platonik.json +39 -0
  144. package/src/icons/sets/roughday.json +25 -0
  145. package/src/icons/sets/shared.json +12 -0
  146. package/src/icons/sets/slopcamera.json +47 -0
  147. package/src/icons/sets/soundfish.json +43 -0
  148. package/src/icons/sets/sponge.json +51 -0
  149. package/src/icons/sets/stripe-history.json +39 -0
  150. package/src/icons/sets/wordcell.json +51 -0
  151. package/src/icons/shared/agent-skill.svg +4 -0
  152. package/src/icons/shared/cli.svg +5 -0
  153. package/src/icons/shared/privacy.svg +3 -0
  154. package/src/icons/shared/research.svg +7 -0
  155. package/src/icons/shared/sdk.svg +3 -0
  156. package/src/icons/slopcamera/diagram.svg +3 -0
  157. package/src/icons/slopcamera/direct-scene.svg +5 -0
  158. package/src/icons/slopcamera/edit-video.svg +17 -0
  159. package/src/icons/slopcamera/mcp.svg +3 -0
  160. package/src/icons/slopcamera/native-world.svg +3 -0
  161. package/src/icons/slopcamera/slopcamera.svg +11 -0
  162. package/src/icons/soundfish/agent-ui.svg +7 -0
  163. package/src/icons/soundfish/collaborate.svg +5 -0
  164. package/src/icons/soundfish/compose.svg +3 -0
  165. package/src/icons/soundfish/hear.svg +6 -0
  166. package/src/icons/soundfish/human-ui.svg +6 -0
  167. package/src/icons/soundfish/share.svg +3 -0
  168. package/src/icons/soundfish/soundfish.svg +6 -0
  169. package/src/icons/sponge/api.svg +3 -0
  170. package/src/icons/sponge/documents.svg +3 -0
  171. package/src/icons/sponge/library.svg +3 -0
  172. package/src/icons/sponge/one-question.svg +5 -0
  173. package/src/icons/sponge/people-direct.svg +5 -0
  174. package/src/icons/sponge/read.svg +3 -0
  175. package/src/icons/sponge/save.svg +4 -0
  176. package/src/icons/sponge/sponge.svg +7 -0
  177. package/src/icons/stripe-history/company-history.svg +3 -0
  178. package/src/icons/stripe-history/evidence.svg +4 -0
  179. package/src/icons/stripe-history/independence.svg +7 -0
  180. package/src/icons/stripe-history/publications.svg +11 -0
  181. package/src/icons/stripe-history/sources.svg +6 -0
  182. package/src/icons/stripe-history/stripe-history.svg +3 -0
  183. package/src/icons/wordcell/backlinks.svg +6 -0
  184. package/src/icons/wordcell/capture.svg +6 -0
  185. package/src/icons/wordcell/git-provenance.svg +4 -0
  186. package/src/icons/wordcell/kb.svg +4 -0
  187. package/src/icons/wordcell/markdown.svg +4 -0
  188. package/src/icons/wordcell/scopes.svg +3 -0
  189. package/src/icons/wordcell/search.svg +7 -0
  190. package/src/icons.generated.ts +734 -0
  191. package/src/icons.ts +51 -0
  192. package/src/index.ts +275 -0
  193. package/src/lantern-material.css +213 -0
  194. package/src/launch.ts +624 -0
  195. package/src/marketing-assets/UPSTREAM.md +18 -0
  196. package/src/marketing-assets/cells.svg +1 -0
  197. package/src/marketing-assets/grain.svg +1 -0
  198. package/src/marketing-forced-colors.css +12 -0
  199. package/src/mockups/client.tsx +415 -0
  200. package/src/mockups/core.tsx +318 -0
  201. package/src/mockups/frames.tsx +368 -0
  202. package/src/mockups/index.ts +14 -0
  203. package/src/mockups/surfaces.tsx +681 -0
  204. package/src/mockups.css +2607 -0
  205. package/src/palette-appearance.ts +45 -0
  206. package/src/palette-bridge.css +124 -0
  207. package/src/palette-color.ts +41 -0
  208. package/src/palette-system.css +721 -0
  209. package/src/palette-themes.ts +23 -0
  210. package/src/palette-tokens.stylex.ts +519 -0
  211. package/src/palettes.css +3 -0
  212. package/src/palettes.ts +161 -0
  213. package/src/paper-theme.css +244 -0
  214. package/src/plain-publication.css +1241 -0
  215. package/src/plain-site.css +397 -0
  216. package/src/platforms.ts +151 -0
  217. package/src/portfolio.generated.json +1595 -0
  218. package/src/portfolio.generated.ts +1596 -0
  219. package/src/portfolio.ts +226 -0
  220. package/src/product-marketing-foundation.css +433 -0
  221. package/src/product-marketing-preset.css +261 -0
  222. package/src/product-marketing.css +2186 -0
  223. package/src/provider-marks.generated.ts +112 -0
  224. package/src/provider-marks.ts +143 -0
  225. package/src/react/animated-rail-stage.stylex.ts +15 -0
  226. package/src/react/animated-rail-stage.tsx +51 -0
  227. package/src/react/app-shell.stylex.ts +104 -0
  228. package/src/react/app-shell.tsx +121 -0
  229. package/src/react/article.tsx +602 -0
  230. package/src/react/aurora-dots-background.tsx +34 -0
  231. package/src/react/charts.stylex.ts +563 -0
  232. package/src/react/charts.tsx +610 -0
  233. package/src/react/chat.stylex.ts +34 -0
  234. package/src/react/chat.tsx +155 -0
  235. package/src/react/design-gallery.tsx +943 -0
  236. package/src/react/design-palette.stylex.ts +124 -0
  237. package/src/react/design-palette.tsx +196 -0
  238. package/src/react/design-theme-context.tsx +41 -0
  239. package/src/react/effects.stylex.ts +325 -0
  240. package/src/react/fader.stylex.ts +71 -0
  241. package/src/react/fader.tsx +151 -0
  242. package/src/react/foil-card-math.ts +100 -0
  243. package/src/react/foil-card-surface.stylex.ts +326 -0
  244. package/src/react/foil-card-surface.tsx +742 -0
  245. package/src/react/foil-mark.tsx +35 -0
  246. package/src/react/foil.stylex.ts +163 -0
  247. package/src/react/haptics.ts +228 -0
  248. package/src/react/hero-backdrop.tsx +22 -0
  249. package/src/react/index.ts +38 -0
  250. package/src/react/keyboard-shortcuts.ts +228 -0
  251. package/src/react/lantern-material-gallery.tsx +166 -0
  252. package/src/react/lantern-material.stylex.ts +39 -0
  253. package/src/react/launch-beats.tsx +73 -0
  254. package/src/react/navigation-rail.stylex.ts +130 -0
  255. package/src/react/navigation-rail.tsx +228 -0
  256. package/src/react/particle-halo.tsx +115 -0
  257. package/src/react/phaser-dots.tsx +501 -0
  258. package/src/react/platform-icons.tsx +94 -0
  259. package/src/react/platform-install.stylex.ts +385 -0
  260. package/src/react/platform-install.tsx +389 -0
  261. package/src/react/playback-transport.stylex.ts +14 -0
  262. package/src/react/playback-transport.tsx +112 -0
  263. package/src/react/procedural-backdrop.tsx +192 -0
  264. package/src/react/procedural-recipe.ts +323 -0
  265. package/src/react/product-marketing.stylex.ts +4469 -0
  266. package/src/react/product-marketing.tsx +1611 -0
  267. package/src/react/production-data-preview-notice.stylex.ts +40 -0
  268. package/src/react/production-data-preview-notice.tsx +34 -0
  269. package/src/react/provider-mark.stylex.ts +132 -0
  270. package/src/react/provider-mark.tsx +120 -0
  271. package/src/react/relative-time.tsx +117 -0
  272. package/src/react/route-state.stylex.ts +39 -0
  273. package/src/react/route-state.tsx +350 -0
  274. package/src/react/server.ts +11 -0
  275. package/src/react/social-kit-panel.tsx +103 -0
  276. package/src/react/sticky-offset.tsx +33 -0
  277. package/src/react/surfaces.stylex.ts +179 -0
  278. package/src/react/surfaces.tsx +330 -0
  279. package/src/react/syntax-code.tsx +33 -0
  280. package/src/react/theme-color-sync.ts +1 -0
  281. package/src/react/theme-resolution.ts +11 -0
  282. package/src/react/theme.stylex.ts +276 -0
  283. package/src/react/theme.tsx +402 -0
  284. package/src/reading.css +72 -0
  285. package/src/relative-time.ts +185 -0
  286. package/src/reset.css +2 -0
  287. package/src/site-shell.css +16 -0
  288. package/src/status-page-html.ts +63 -0
  289. package/src/status-page.css +276 -0
  290. package/src/status-page.ts +323 -0
  291. package/src/styles.css +21 -0
  292. package/src/syntax-code-lexers.ts +303 -0
  293. package/src/syntax-highlighting.css +78 -0
  294. package/src/syntax-highlighting.ts +477 -0
  295. package/src/syntax-tokens.ts +33 -0
  296. package/src/testing.ts +307 -0
  297. package/src/tokens.css +3 -0
  298. package/src/typography.css +86 -0
  299. package/vendor/evilcharts/LICENSE +21 -0
  300. package/vendor/evilcharts/UPSTREAM.md +14 -0
  301. package/vendor/platform-marks/LICENSE +30 -0
  302. package/vendor/platform-marks/UPSTREAM.md +15 -0
  303. package/vendor/platform-marks/apple.svg +1 -0
  304. package/vendor/platform-marks/linux.svg +1 -0
  305. package/vendor/provider-marks/CRUSH-LICENSE.md +134 -0
  306. package/vendor/provider-marks/LICENSE +21 -0
  307. package/vendor/provider-marks/UPSTREAM.md +27 -0
  308. package/vendor/provider-marks/aider.svg +3 -0
  309. package/vendor/provider-marks/crush-heartbit.svg +8 -0
  310. package/vendor/provider-marks/lobehub/alibabacloud-color.svg +1 -0
  311. package/vendor/provider-marks/lobehub/alibabacloud.svg +1 -0
  312. package/vendor/provider-marks/lobehub/amp-color.svg +1 -0
  313. package/vendor/provider-marks/lobehub/amp.svg +1 -0
  314. package/vendor/provider-marks/lobehub/anthropic.svg +1 -0
  315. package/vendor/provider-marks/lobehub/claude-color.svg +1 -0
  316. package/vendor/provider-marks/lobehub/claude.svg +1 -0
  317. package/vendor/provider-marks/lobehub/claudecode-color.svg +1 -0
  318. package/vendor/provider-marks/lobehub/claudecode.svg +1 -0
  319. package/vendor/provider-marks/lobehub/codex-color.svg +1 -0
  320. package/vendor/provider-marks/lobehub/codex.svg +1 -0
  321. package/vendor/provider-marks/lobehub/cursor.svg +1 -0
  322. package/vendor/provider-marks/lobehub/deepseek-color.svg +1 -0
  323. package/vendor/provider-marks/lobehub/deepseek.svg +1 -0
  324. package/vendor/provider-marks/lobehub/devin-color.svg +1 -0
  325. package/vendor/provider-marks/lobehub/devin.svg +1 -0
  326. package/vendor/provider-marks/lobehub/gemini-color.svg +1 -0
  327. package/vendor/provider-marks/lobehub/gemini.svg +1 -0
  328. package/vendor/provider-marks/lobehub/geminicli-color.svg +1 -0
  329. package/vendor/provider-marks/lobehub/geminicli.svg +1 -0
  330. package/vendor/provider-marks/lobehub/goose.svg +1 -0
  331. package/vendor/provider-marks/lobehub/meta-color.svg +1 -0
  332. package/vendor/provider-marks/lobehub/meta.svg +1 -0
  333. package/vendor/provider-marks/lobehub/mistral-color.svg +1 -0
  334. package/vendor/provider-marks/lobehub/mistral.svg +1 -0
  335. package/vendor/provider-marks/lobehub/moonshot.svg +1 -0
  336. package/vendor/provider-marks/lobehub/nvidia-color.svg +1 -0
  337. package/vendor/provider-marks/lobehub/nvidia.svg +1 -0
  338. package/vendor/provider-marks/lobehub/openai.svg +1 -0
  339. package/vendor/provider-marks/lobehub/opencode.svg +1 -0
  340. package/vendor/provider-marks/lobehub/perplexity-color.svg +1 -0
  341. package/vendor/provider-marks/lobehub/perplexity.svg +1 -0
  342. package/vendor/provider-marks/lobehub/qwen-color.svg +1 -0
  343. package/vendor/provider-marks/lobehub/qwen.svg +1 -0
  344. package/vendor/provider-marks/lobehub/xai.svg +1 -0
  345. package/vendor/provider-marks/lobehub/zai.svg +1 -0
@@ -0,0 +1,1209 @@
1
+ import {
2
+ ARTICLE_BYLINE_PREFIX,
3
+ ARTICLE_SOURCES_HEADING,
4
+ ARTICLE_TOC_LABEL,
5
+ articleProvenanceSentence,
6
+ assertArticleAuthor,
7
+ assertArticleCalloutTone,
8
+ assertArticleDates,
9
+ assertArticleHref,
10
+ formatArticleDate
11
+ } from "./chunk-77391vmq.js";
12
+
13
+ // src/palette-color.ts
14
+ function channels(hex) {
15
+ if (!/^#[0-9a-f]{6}$/iu.test(hex))
16
+ throw new Error("Palette colors must be six-digit hex values.");
17
+ return [Number.parseInt(hex.slice(1, 3), 16), Number.parseInt(hex.slice(3, 5), 16), Number.parseInt(hex.slice(5, 7), 16)];
18
+ }
19
+ function mixPaletteColor(color, toward, amount) {
20
+ const target = channels(toward);
21
+ return `#${channels(color).map((value, index) => Math.round(value * (1 - amount) + (target[index] ?? 0) * amount).toString(16).padStart(2, "0")).join("")}`;
22
+ }
23
+ function luminance(hex) {
24
+ const linearize = (channel) => {
25
+ const value = channel / 255;
26
+ return value <= 0.04045 ? value / 12.92 : ((value + 0.055) / 1.055) ** 2.4;
27
+ };
28
+ const [red, green, blue] = channels(hex);
29
+ return linearize(red) * 0.2126 + linearize(green) * 0.7152 + linearize(blue) * 0.0722;
30
+ }
31
+ function paletteContrast(a, b) {
32
+ const first = luminance(a);
33
+ const second = luminance(b);
34
+ return (Math.max(first, second) + 0.05) / (Math.min(first, second) + 0.05);
35
+ }
36
+ function readablePaletteColor(color, toward, backgrounds, minimum) {
37
+ for (let step = 0;step <= 100; step += 1) {
38
+ const candidate = mixPaletteColor(color, toward, step / 100);
39
+ if (backgrounds.every((background) => paletteContrast(candidate, background) >= minimum))
40
+ return candidate;
41
+ }
42
+ throw new Error("The authored palette cannot meet its contrast contract.");
43
+ }
44
+
45
+ // src/palettes.ts
46
+ var designPalettes = ["catppuccin", "gruvbox", "rose-pine", "tokyo-night", "paper"];
47
+ var designPaletteLabels = {
48
+ catppuccin: "Catppuccin",
49
+ gruvbox: "Gruvbox",
50
+ "rose-pine": "Rosé Pine",
51
+ "tokyo-night": "Tokyo Night",
52
+ paper: "Paper"
53
+ };
54
+ function isDesignPalette(value) {
55
+ return typeof value === "string" && designPalettes.some((palette) => palette === value);
56
+ }
57
+ var designPaletteSources = {
58
+ paper: {
59
+ light: {
60
+ background: "#f8f7f4",
61
+ surface: "#fffefa",
62
+ raised: "#fffefa",
63
+ hover: "#ebe8e3",
64
+ text: "#1c1917",
65
+ muted: "#6f6962",
66
+ border: "#8b8278",
67
+ primary: "#1f5eea",
68
+ danger: "#b23c34",
69
+ warning: "#a65f00",
70
+ success: "#26814d",
71
+ info: "#1f5eea",
72
+ violet: "#7959a5",
73
+ rose: "#a44b65"
74
+ },
75
+ dark: {
76
+ background: "#12100f",
77
+ surface: "#1d1a18",
78
+ raised: "#211d1a",
79
+ hover: "#292522",
80
+ text: "#f5f2ed",
81
+ muted: "#aaa29a",
82
+ border: "#827a72",
83
+ primary: "#8fb0ff",
84
+ danger: "#ef8c82",
85
+ warning: "#efae55",
86
+ success: "#5fc98b",
87
+ info: "#8fb0ff",
88
+ violet: "#b7a0dc",
89
+ rose: "#db91aa"
90
+ }
91
+ },
92
+ catppuccin: {
93
+ dark: {
94
+ background: "#1e1e2e",
95
+ surface: "#181825",
96
+ raised: "#313244",
97
+ hover: "#45475a",
98
+ text: "#cdd6f4",
99
+ muted: "#a6adc8",
100
+ border: "#7f849c",
101
+ primary: "#89b4fa",
102
+ danger: "#f38ba8",
103
+ warning: "#f9e2af",
104
+ success: "#a6e3a1",
105
+ info: "#89dceb",
106
+ violet: "#cba6f7",
107
+ rose: "#f5c2e7"
108
+ },
109
+ light: {
110
+ background: "#eff1f5",
111
+ surface: "#e6e9ef",
112
+ raised: "#dce0e8",
113
+ hover: "#ccd0da",
114
+ text: "#4c4f69",
115
+ muted: "#6c6f85",
116
+ border: "#7c7f93",
117
+ primary: "#1e66f5",
118
+ danger: "#d20f39",
119
+ warning: "#df8e1d",
120
+ success: "#40a02b",
121
+ info: "#179299",
122
+ violet: "#8839ef",
123
+ rose: "#ea76cb"
124
+ }
125
+ },
126
+ gruvbox: {
127
+ dark: {
128
+ background: "#282828",
129
+ surface: "#1d2021",
130
+ raised: "#3c3836",
131
+ hover: "#504945",
132
+ text: "#ebdbb2",
133
+ muted: "#bdae93",
134
+ border: "#928374",
135
+ primary: "#83a598",
136
+ danger: "#fb4934",
137
+ warning: "#fabd2f",
138
+ success: "#b8bb26",
139
+ info: "#8ec07c",
140
+ violet: "#d3869b",
141
+ rose: "#fe8019"
142
+ },
143
+ light: {
144
+ background: "#fbf1c7",
145
+ surface: "#f9f5d7",
146
+ raised: "#ebdbb2",
147
+ hover: "#d5c4a1",
148
+ text: "#3c3836",
149
+ muted: "#665c54",
150
+ border: "#7c6f64",
151
+ primary: "#076678",
152
+ danger: "#9d0006",
153
+ warning: "#b57614",
154
+ success: "#79740e",
155
+ info: "#427b58",
156
+ violet: "#8f3f71",
157
+ rose: "#af3a03"
158
+ }
159
+ },
160
+ "rose-pine": {
161
+ dark: {
162
+ background: "#191724",
163
+ surface: "#1f1d2e",
164
+ raised: "#26233a",
165
+ hover: "#403d52",
166
+ text: "#e0def4",
167
+ muted: "#908caa",
168
+ border: "#908caa",
169
+ primary: "#c4a7e7",
170
+ danger: "#eb6f92",
171
+ warning: "#f6c177",
172
+ success: "#9ccfd8",
173
+ info: "#ebbcba",
174
+ violet: "#c4a7e7",
175
+ rose: "#ebbcba"
176
+ },
177
+ light: {
178
+ background: "#faf4ed",
179
+ surface: "#fffaf3",
180
+ raised: "#f2e9e1",
181
+ hover: "#dfdad9",
182
+ text: "#575279",
183
+ muted: "#797593",
184
+ border: "#797593",
185
+ primary: "#907aa9",
186
+ danger: "#b4637a",
187
+ warning: "#ea9d34",
188
+ success: "#286983",
189
+ info: "#56949f",
190
+ violet: "#907aa9",
191
+ rose: "#d7827e"
192
+ }
193
+ },
194
+ "tokyo-night": {
195
+ dark: {
196
+ background: "#1a1b26",
197
+ surface: "#16161e",
198
+ raised: "#24283b",
199
+ hover: "#292e42",
200
+ text: "#c0caf5",
201
+ muted: "#a9b1d6",
202
+ border: "#737aa2",
203
+ primary: "#7aa2f7",
204
+ danger: "#f7768e",
205
+ warning: "#e0af68",
206
+ success: "#9ece6a",
207
+ info: "#7dcfff",
208
+ violet: "#bb9af7",
209
+ rose: "#ff9e64"
210
+ },
211
+ light: {
212
+ background: "#e1e2e7",
213
+ surface: "#d0d5e3",
214
+ raised: "#c4c8da",
215
+ hover: "#b7c1e3",
216
+ text: "#3760bf",
217
+ muted: "#6172b0",
218
+ border: "#6172b0",
219
+ primary: "#2e7de9",
220
+ danger: "#f52a65",
221
+ warning: "#8c6c3e",
222
+ success: "#587539",
223
+ info: "#007197",
224
+ violet: "#9854f1",
225
+ rose: "#b15c00"
226
+ }
227
+ }
228
+ };
229
+ function createPalette(source, mode) {
230
+ const surfaces = [source.background, source.surface, source.raised, source.hover];
231
+ const endpoint = mode === "dark" ? "#ffffff" : "#000000";
232
+ const foreground = readablePaletteColor(source.text, endpoint, surfaces, 7);
233
+ const muted = readablePaletteColor(source.muted, endpoint, surfaces, 4.6);
234
+ const status = (seed) => {
235
+ const soft = mixPaletteColor(source.background, seed, 0.12);
236
+ const color = readablePaletteColor(seed, endpoint, [...surfaces, soft], 4.6);
237
+ const onColor = paletteContrast(color, source.background) >= 4.5 ? source.background : endpoint === "#ffffff" ? "#000000" : "#ffffff";
238
+ return {
239
+ color,
240
+ foreground: onColor,
241
+ soft
242
+ };
243
+ };
244
+ const primary = status(source.primary);
245
+ const danger = status(source.danger);
246
+ const warning = status(source.warning);
247
+ const success = status(source.success);
248
+ const info = status(source.info);
249
+ return Object.freeze({
250
+ background: source.background,
251
+ foreground,
252
+ muted,
253
+ faint: muted,
254
+ grid: source.raised,
255
+ line: source.hover,
256
+ controlBorder: readablePaletteColor(source.border, endpoint, surfaces, 3.1),
257
+ surface: source.surface,
258
+ surfaceRaised: source.raised,
259
+ surfaceHover: source.hover,
260
+ card: source.surface,
261
+ cardForeground: foreground,
262
+ popover: source.raised,
263
+ popoverForeground: foreground,
264
+ primary: primary.color,
265
+ primaryForeground: primary.foreground,
266
+ primarySoft: primary.soft,
267
+ secondary: source.raised,
268
+ secondaryForeground: foreground,
269
+ accent: primary.soft,
270
+ accentForeground: foreground,
271
+ focus: primary.color,
272
+ scrim: mode === "dark" ? "#000000b8" : "#00000070",
273
+ disabled: source.raised,
274
+ disabledForeground: muted,
275
+ inverse: foreground,
276
+ inverseForeground: source.background,
277
+ danger: danger.color,
278
+ dangerForeground: danger.foreground,
279
+ dangerSoft: danger.soft,
280
+ warning: warning.color,
281
+ warningForeground: warning.foreground,
282
+ warningSoft: warning.soft,
283
+ success: success.color,
284
+ successForeground: success.foreground,
285
+ successSoft: success.soft,
286
+ info: info.color,
287
+ infoForeground: info.foreground,
288
+ infoSoft: info.soft,
289
+ chart1: readablePaletteColor(source.rose, endpoint, surfaces, 4.6),
290
+ chart2: success.color,
291
+ chart3: info.color,
292
+ chart4: warning.color,
293
+ chart5: readablePaletteColor(source.violet, endpoint, surfaces, 4.6)
294
+ });
295
+ }
296
+ var paletteColors = Object.freeze({
297
+ paper: Object.freeze({
298
+ light: Object.freeze({
299
+ ...createPalette(designPaletteSources.paper.light, "light"),
300
+ grid: "#dfdcd6",
301
+ line: "#b9b3ab",
302
+ secondary: "#ebe8e3"
303
+ }),
304
+ dark: Object.freeze({
305
+ ...createPalette(designPaletteSources.paper.dark, "dark"),
306
+ grid: "#302b27",
307
+ line: "#514a44",
308
+ secondary: "#292522"
309
+ })
310
+ }),
311
+ catppuccin: Object.freeze({
312
+ light: createPalette(designPaletteSources.catppuccin.light, "light"),
313
+ dark: createPalette(designPaletteSources.catppuccin.dark, "dark")
314
+ }),
315
+ gruvbox: Object.freeze({
316
+ light: createPalette(designPaletteSources.gruvbox.light, "light"),
317
+ dark: createPalette(designPaletteSources.gruvbox.dark, "dark")
318
+ }),
319
+ "rose-pine": Object.freeze({
320
+ light: createPalette(designPaletteSources["rose-pine"].light, "light"),
321
+ dark: createPalette(designPaletteSources["rose-pine"].dark, "dark")
322
+ }),
323
+ "tokyo-night": Object.freeze({
324
+ light: createPalette(designPaletteSources["tokyo-night"].light, "light"),
325
+ dark: createPalette(designPaletteSources["tokyo-night"].dark, "dark")
326
+ })
327
+ });
328
+ // src/appearance.ts
329
+ var designThemes = ["light", "dark", "system"];
330
+ var defaultDesignTheme = "system";
331
+ var designThemeStorageKey = "hraness-design-theme-v1";
332
+ function isDesignTheme(value) {
333
+ return typeof value === "string" && designThemes.some((theme) => theme === value);
334
+ }
335
+ function normalizeDesignTheme(value) {
336
+ return isDesignTheme(value) ? value : defaultDesignTheme;
337
+ }
338
+ function designThemeLabel(theme, labels) {
339
+ return labels?.[theme] ?? `${theme.charAt(0).toUpperCase()}${theme.slice(1)}`;
340
+ }
341
+ function resolveDesignTheme(theme, systemPrefersDark) {
342
+ return theme === "system" ? systemPrefersDark ? "dark" : "light" : theme;
343
+ }
344
+
345
+ // src/palette-appearance.ts
346
+ var defaultDesignPalettePreference = Object.freeze({
347
+ palette: "catppuccin",
348
+ mode: "dark"
349
+ });
350
+ var designPaletteStorageKey = "hraness-design-palette-v1";
351
+ function parseDesignPalettePreference(value) {
352
+ if (typeof value === "string") {
353
+ if (value.length > 256)
354
+ return null;
355
+ try {
356
+ value = JSON.parse(value);
357
+ } catch {
358
+ return null;
359
+ }
360
+ }
361
+ if (typeof value !== "object" || value === null || Array.isArray(value))
362
+ return null;
363
+ const record = value;
364
+ if (!isDesignPalette(record.palette) || !isDesignTheme(record.mode))
365
+ return null;
366
+ return Object.freeze({
367
+ palette: record.palette,
368
+ mode: record.mode
369
+ });
370
+ }
371
+ function normalizeDesignPalettePreference(value, fallback = defaultDesignPalettePreference) {
372
+ return parseDesignPalettePreference(value) ?? parseDesignPalettePreference(fallback) ?? defaultDesignPalettePreference;
373
+ }
374
+ function resolveDesignPalettePreference(preference, systemPrefersDark) {
375
+ return {
376
+ palette: preference.palette,
377
+ mode: resolveDesignTheme(preference.mode, systemPrefersDark)
378
+ };
379
+ }
380
+ // src/palette-themes.ts
381
+ import * as stylex from "@stylexjs/stylex";
382
+
383
+ // src/palette-tokens.stylex.ts
384
+ var catppuccinLight = {
385
+ x18acsur: "xadus2s x18acsur",
386
+ $$css: true
387
+ };
388
+ var catppuccinDark = {
389
+ x18acsur: "x18wthyl x18acsur",
390
+ $$css: true
391
+ };
392
+ var gruvboxLight = {
393
+ x18acsur: "xdktuxt x18acsur",
394
+ $$css: true
395
+ };
396
+ var gruvboxDark = {
397
+ x18acsur: "x1fsd05x x18acsur",
398
+ $$css: true
399
+ };
400
+ var rosePineLight = {
401
+ x18acsur: "x131glkb x18acsur",
402
+ $$css: true
403
+ };
404
+ var rosePineDark = {
405
+ x18acsur: "xivpxii x18acsur",
406
+ $$css: true
407
+ };
408
+ var tokyoNightLight = {
409
+ x18acsur: "x11phk89 x18acsur",
410
+ $$css: true
411
+ };
412
+ var tokyoNightDark = {
413
+ x18acsur: "xgp1gpt x18acsur",
414
+ $$css: true
415
+ };
416
+ var paperLight = {
417
+ x18acsur: "xjfxk3y x18acsur",
418
+ $$css: true
419
+ };
420
+ var paperDark = {
421
+ x18acsur: "x1lresar x18acsur",
422
+ $$css: true
423
+ };
424
+
425
+ // src/palette-themes.ts
426
+ var classes = {
427
+ paper: {
428
+ light: stylex.props(paperLight).className,
429
+ dark: stylex.props(paperDark).className
430
+ },
431
+ catppuccin: {
432
+ light: stylex.props(catppuccinLight).className,
433
+ dark: stylex.props(catppuccinDark).className
434
+ },
435
+ gruvbox: {
436
+ light: stylex.props(gruvboxLight).className,
437
+ dark: stylex.props(gruvboxDark).className
438
+ },
439
+ "rose-pine": {
440
+ light: stylex.props(rosePineLight).className,
441
+ dark: stylex.props(rosePineDark).className
442
+ },
443
+ "tokyo-night": {
444
+ light: stylex.props(tokyoNightLight).className,
445
+ dark: stylex.props(tokyoNightDark).className
446
+ }
447
+ };
448
+ function getDesignPaletteTheme(palette, mode) {
449
+ return {
450
+ className: `hraness-palette ${classes[palette][mode]}`,
451
+ background: paletteColors[palette][mode].background
452
+ };
453
+ }
454
+ // src/article-html.ts
455
+ var ROOT_CLASS = "plain-site plain-publication plain-publication--embedded";
456
+ var SEPARATOR = '<span aria-hidden="true"> · </span>';
457
+ var ESCAPES = {
458
+ '"': "&quot;",
459
+ "&": "&amp;",
460
+ "'": "&#x27;",
461
+ "<": "&lt;",
462
+ ">": "&gt;"
463
+ };
464
+ function escapeArticleHtml(value) {
465
+ return value.replace(/["&'<>]/gu, (character) => ESCAPES[character] ?? character);
466
+ }
467
+ function classes2(...values) {
468
+ return values.filter((value) => value !== undefined && value !== "").join(" ");
469
+ }
470
+ function dateHtml(label, value) {
471
+ return `${label} <time dateTime="${escapeArticleHtml(value)}">${escapeArticleHtml(formatArticleDate(value))}</time>`;
472
+ }
473
+ function present(value) {
474
+ return value !== undefined && value !== "";
475
+ }
476
+ function renderArticleBylineHtml(author) {
477
+ assertArticleAuthor(author);
478
+ const name = escapeArticleHtml(author.name);
479
+ const linked = author.href === undefined ? name : `<a href="${escapeArticleHtml(author.href)}" rel="author">${name}</a>`;
480
+ return `<span class="plain-publication__byline" data-author-kind="${author.kind}">${ARTICLE_BYLINE_PREFIX} ${linked}</span>`;
481
+ }
482
+ function renderArticleProvenanceHtml(provenance) {
483
+ const sentence = articleProvenanceSentence(provenance);
484
+ return `<p class="plain-publication__provenance" data-drafting="${escapeArticleHtml(provenance.drafting)}" data-reviewer-type="${escapeArticleHtml(provenance.review?.reviewerType ?? "none")}">${escapeArticleHtml(sentence)}</p>`;
485
+ }
486
+ function renderArticleHtml(input) {
487
+ const headingId = input.headingId ?? "article-title";
488
+ const {
489
+ published,
490
+ updated
491
+ } = input;
492
+ assertArticleDates(updated === undefined ? {
493
+ published
494
+ } : {
495
+ published,
496
+ updated
497
+ });
498
+ const toc = input.toc ?? [];
499
+ for (const item of toc) {
500
+ if (!item.href.startsWith("#") || item.href.length < 2)
501
+ throw new RangeError("Contents links must point to a heading in this article.");
502
+ }
503
+ const tocId = `${headingId}-contents`;
504
+ const meta = [input.author === undefined ? "" : renderArticleBylineHtml(input.author) + SEPARATOR, dateHtml("Published", published), updated === undefined ? "" : SEPARATOR + dateHtml("Updated", updated)].join("");
505
+ const header = ['<header class="plain-publication__article-header">', present(input.eyebrow) ? `<p class="plain-publication__eyebrow">${escapeArticleHtml(input.eyebrow)}</p>` : "", `<h1 id="${escapeArticleHtml(headingId)}">${escapeArticleHtml(input.heading)}</h1>`, present(input.dek) ? `<p class="plain-publication__article-dek">${escapeArticleHtml(input.dek)}</p>` : "", `<p class="plain-publication__article-meta">${meta}</p>`, input.provenance === null ? "" : renderArticleProvenanceHtml(input.provenance), "</header>"].join("");
506
+ const nav = toc.length === 0 ? "" : [`<nav aria-labelledby="${escapeArticleHtml(tocId)}" class="plain-publication__toc">`, `<p id="${escapeArticleHtml(tocId)}">${escapeArticleHtml(input.tocLabel ?? ARTICLE_TOC_LABEL)}</p>`, "<ol>", ...toc.map((item) => `<li><a href="${escapeArticleHtml(item.href)}">${escapeArticleHtml(item.label)}</a></li>`), "</ol></nav>"].join("");
507
+ return [`<article aria-labelledby="${escapeArticleHtml(headingId)}" class="${escapeArticleHtml(classes2(ROOT_CLASS, "plain-publication__article", input.className))}" data-hraness-article="" data-toc="${toc.length > 0 ? "aside" : "none"}"${input.id === undefined ? "" : ` id="${escapeArticleHtml(input.id)}"`}>`, header, '<div class="plain-publication__article-layout">', nav, `<div class="plain-publication__article-body">${input.bodyHtml}</div>`, "</div>", present(input.afterHtml) ? `<footer class="plain-publication__article-footer">${input.afterHtml}</footer>` : "", "</article>"].join("");
508
+ }
509
+ function renderArticleSourcesHtml({
510
+ heading = ARTICLE_SOURCES_HEADING,
511
+ headingId = "article-sources",
512
+ sources
513
+ }) {
514
+ if (sources.length === 0)
515
+ return "";
516
+ for (const source of sources)
517
+ assertArticleHref(source.href);
518
+ return [`<section aria-labelledby="${escapeArticleHtml(headingId)}" class="plain-publication__sources">`, `<h2 id="${escapeArticleHtml(headingId)}">${escapeArticleHtml(heading)}</h2>`, "<ol>", ...sources.map((source) => [`<li><a href="${escapeArticleHtml(source.href)}">${escapeArticleHtml(source.title)}</a>`, "<span>", present(source.publisher) ? escapeArticleHtml(source.publisher) + SEPARATOR : "", dateHtml("Checked", source.checkedOn), "</span></li>"].join("")), "</ol></section>"].join("");
519
+ }
520
+ function renderArticleCalloutHtml(input) {
521
+ const tone = input.tone ?? "note";
522
+ assertArticleCalloutTone(tone);
523
+ const body = input.text === undefined ? input.bodyHtml : `<p>${escapeArticleHtml(input.text)}</p>`;
524
+ return `<div class="plain-publication__callout" data-tone="${tone}" role="note">${present(input.label) ? `<strong>${escapeArticleHtml(input.label)}</strong>` : ""}${body}</div>`;
525
+ }
526
+ function assertArticleMark(mark) {
527
+ if (!mark.startsWith("data:image/svg+xml,"))
528
+ assertArticleHref(mark);
529
+ }
530
+ function renderArticleRelatedHtml({
531
+ heading = "Related products",
532
+ headingId = "article-related-products",
533
+ items
534
+ }) {
535
+ if (items.length === 0)
536
+ return "";
537
+ for (const item of items) {
538
+ assertArticleHref(item.href);
539
+ if (present(item.mark))
540
+ assertArticleMark(item.mark);
541
+ }
542
+ return [`<section aria-labelledby="${escapeArticleHtml(headingId)}" class="plain-publication__related">`, `<div class="plain-publication__section-heading"><h2 id="${escapeArticleHtml(headingId)}">${escapeArticleHtml(heading)}</h2></div>`, '<div class="plain-publication__related-grid">', ...items.map((item) => [`<a href="${escapeArticleHtml(item.href)}">`, present(item.mark) ? `<img alt="" class="plain-publication__related-mark" decoding="async" height="44" src="${escapeArticleHtml(item.mark)}" width="44">` : "", `<span class="plain-publication__related-text"><strong>${escapeArticleHtml(item.name)}</strong>`, `<span>${escapeArticleHtml(item.role ?? item.relationship)}</span></span></a>`].join("")), "</div></section>"].join("");
543
+ }
544
+ function renderArticleIndexHtml({
545
+ className,
546
+ heading,
547
+ headingId,
548
+ headingLevel = 2,
549
+ id,
550
+ items,
551
+ summary
552
+ }) {
553
+ if (![1, 2, 3, 4, 5].includes(headingLevel))
554
+ throw new RangeError("Article index heading level must be 1 to 5.");
555
+ const hrefs = new Set;
556
+ for (const item of items) {
557
+ assertArticleHref(item.href);
558
+ assertArticleDates(item.updated === undefined ? {
559
+ published: item.published
560
+ } : {
561
+ published: item.published,
562
+ updated: item.updated
563
+ });
564
+ if (hrefs.has(item.href))
565
+ throw new RangeError(`Article index lists ${item.href} more than once.`);
566
+ hrefs.add(item.href);
567
+ }
568
+ const heading1 = `h${headingLevel}`;
569
+ const entry = `h${headingLevel + 1}`;
570
+ return [`<section aria-labelledby="${escapeArticleHtml(headingId)}" class="${escapeArticleHtml(classes2(ROOT_CLASS, "plain-publication__list", className))}" data-hraness-article-index=""${id === undefined ? "" : ` id="${escapeArticleHtml(id)}"`}>`, `<div class="plain-publication__section-heading"><${heading1} id="${escapeArticleHtml(headingId)}">${escapeArticleHtml(heading)}</${heading1}>`, present(summary) ? `<p>${escapeArticleHtml(summary)}</p>` : "", "</div>", '<div class="plain-publication__article-list">', ...items.map((item) => ['<article class="plain-publication__entry">', present(item.eyebrow) ? `<p class="plain-publication__entry-label">${escapeArticleHtml(item.eyebrow)}</p>` : "", `<${entry} class="plain-publication__entry-title"><a href="${escapeArticleHtml(item.href)}">${escapeArticleHtml(item.title)}</a></${entry}>`, `<p class="plain-publication__entry-dek">${escapeArticleHtml(item.dek)}</p>`, '<p class="plain-publication__entry-meta">', dateHtml("Published", item.published), item.updated === undefined ? "" : SEPARATOR + dateHtml("Updated", item.updated), "</p></article>"].join("")), "</div></section>"].join("");
571
+ }
572
+ // src/status-page.ts
573
+ var STATUS_PAGE_MAX_NEXT = 3;
574
+ var STATUS_PAGE_MAX_ROUTES = 2000;
575
+ var STATUS_PAGE_BACK_LABEL = "Go back";
576
+ var STATUS_PAGE_HINT_PREFIX = "Did you mean";
577
+ var STATUS_PAGE_NEXT_HEADING_ID = "hraness-status-page-next";
578
+ var STATUS_PAGE_AGENT_PREFIX = "AI agents can start at";
579
+ var defaults = {
580
+ "not-found": {
581
+ glyph: "404",
582
+ title: "We can’t find that page",
583
+ summary: "The link may be out of date or mistyped."
584
+ },
585
+ error: {
586
+ glyph: "!",
587
+ title: "This view could not load",
588
+ summary: "Retry this view, or return home and continue from there."
589
+ }
590
+ };
591
+ function assertText(name, value, limit) {
592
+ if (value.trim() === "" || value.length > limit) {
593
+ throw new RangeError(`Status page ${name} must be 1–${limit} characters.`);
594
+ }
595
+ }
596
+ function assertLink(name, link) {
597
+ assertArticleHref(link.href);
598
+ assertText(`${name} label`, link.label, 48);
599
+ if (link.description !== undefined)
600
+ assertText(`${name} description`, link.description, 90);
601
+ }
602
+ var ROUTE_LABEL_LIMIT = 80;
603
+ function hasControlOrSpace(href) {
604
+ for (const character of href) {
605
+ const code = character.codePointAt(0) ?? 0;
606
+ if (code <= 32 || code >= 127 && code <= 159 || /\s/u.test(character))
607
+ return true;
608
+ }
609
+ return false;
610
+ }
611
+ function shortRouteLabel(label) {
612
+ const text = label.trim().replace(/\s+/gu, " ");
613
+ if (text.length <= ROUTE_LABEL_LIMIT)
614
+ return text;
615
+ const cut = text.slice(0, ROUTE_LABEL_LIMIT - 1);
616
+ const space = cut.lastIndexOf(" ");
617
+ return `${(space > ROUTE_LABEL_LIMIT / 2 ? cut.slice(0, space) : cut).trimEnd()}…`;
618
+ }
619
+ function usableRoutes(routes) {
620
+ const usable = [];
621
+ for (const route of routes.slice(0, STATUS_PAGE_MAX_ROUTES)) {
622
+ if (typeof route !== "object" || route === null)
623
+ continue;
624
+ const {
625
+ href,
626
+ label
627
+ } = route;
628
+ if (typeof href !== "string" || typeof label !== "string" || label.trim() === "")
629
+ continue;
630
+ if (!isSitePath(href) || hasControlOrSpace(href))
631
+ continue;
632
+ usable.push({
633
+ href,
634
+ label: shortRouteLabel(label)
635
+ });
636
+ }
637
+ return usable;
638
+ }
639
+ function resolveStatusPage(content = {}) {
640
+ const kind = content.kind ?? "not-found";
641
+ const base = defaults[kind];
642
+ const siteName = content.siteName?.trim();
643
+ if (siteName !== undefined)
644
+ assertText("siteName", siteName, 40);
645
+ const glyph = content.glyph ?? base.glyph;
646
+ assertText("glyph", glyph, 4);
647
+ const title = content.title ?? base.title;
648
+ assertText("title", title, 60);
649
+ const summary = content.summary ?? base.summary;
650
+ assertText("summary", summary, 160);
651
+ const primaryAction = content.primaryAction ?? {
652
+ href: "/",
653
+ label: siteName ? `Go to ${siteName}` : "Go to the homepage"
654
+ };
655
+ assertLink("primaryAction", primaryAction);
656
+ const next = content.next ?? [];
657
+ if (next.length > STATUS_PAGE_MAX_NEXT) {
658
+ throw new RangeError(`A status page lists at most ${STATUS_PAGE_MAX_NEXT} next links; pick the ones that lead to your product.`);
659
+ }
660
+ next.forEach((link) => assertLink("next", link));
661
+ const nextHeading = content.nextHeading ?? "Or start here";
662
+ assertText("nextHeading", nextHeading, 40);
663
+ const routes = usableRoutes(content.routes ?? []);
664
+ if (content.agentIndexHref !== undefined)
665
+ assertArticleHref(content.agentIndexHref);
666
+ return {
667
+ kind,
668
+ glyph,
669
+ title,
670
+ summary,
671
+ primaryAction,
672
+ next,
673
+ nextHeading,
674
+ routes,
675
+ ...content.agentIndexHref === undefined ? {} : {
676
+ agentIndexHref: content.agentIndexHref
677
+ }
678
+ };
679
+ }
680
+ function isSitePath(href) {
681
+ return /^\/(?![/\\])/u.test(href);
682
+ }
683
+ function statusPageRoutesAttribute(routes) {
684
+ if (routes.length === 0)
685
+ return;
686
+ return JSON.stringify(routes.map(({
687
+ href,
688
+ label
689
+ }) => [href, label]));
690
+ }
691
+ function parseStatusPageRoutes(value) {
692
+ if (!value)
693
+ return [];
694
+ let parsed;
695
+ try {
696
+ parsed = JSON.parse(value);
697
+ } catch {
698
+ return [];
699
+ }
700
+ if (!Array.isArray(parsed))
701
+ return [];
702
+ const routes = [];
703
+ for (const entry of parsed.slice(0, STATUS_PAGE_MAX_ROUTES)) {
704
+ if (!Array.isArray(entry))
705
+ continue;
706
+ const [href, label] = entry;
707
+ if (typeof href !== "string" || typeof label !== "string")
708
+ continue;
709
+ if (!isSitePath(href) || label.trim() === "")
710
+ continue;
711
+ routes.push({
712
+ href,
713
+ label
714
+ });
715
+ }
716
+ return routes;
717
+ }
718
+ var MAX_PATH = 160;
719
+ function normalizeStatusPath(value) {
720
+ let path = value.slice(0, MAX_PATH * 4);
721
+ const end = path.search(/[?#]/u);
722
+ if (end !== -1)
723
+ path = path.slice(0, end);
724
+ try {
725
+ path = decodeURIComponent(path);
726
+ } catch {}
727
+ path = path.toLowerCase().split("/").filter((part, index) => index === 0 || part !== "").join("/");
728
+ path = path.replace(/(?:\/index)?\.html?$/u, "");
729
+ while (path.length > 1 && path.endsWith("/"))
730
+ path = path.slice(0, -1);
731
+ if (!path.startsWith("/"))
732
+ path = `/${path}`;
733
+ return path.slice(0, MAX_PATH);
734
+ }
735
+ var MAX_EDITS = 3;
736
+ var BEYOND = MAX_EDITS + 1;
737
+ function editDistance(a, b, limit) {
738
+ if (Math.abs(a.length - b.length) > limit)
739
+ return limit + 1;
740
+ const columns = b.length + 1;
741
+ let before = new Int32Array(columns).fill(BEYOND);
742
+ let previous = Int32Array.from({
743
+ length: columns
744
+ }, (_, index) => Math.min(index, BEYOND));
745
+ let current = new Int32Array(columns).fill(BEYOND);
746
+ for (let i = 1;i <= a.length; i++) {
747
+ const low = Math.max(1, i - limit);
748
+ const high = Math.min(b.length, i + limit);
749
+ current[low - 1] = low === 1 ? Math.min(i, BEYOND) : BEYOND;
750
+ if (high < b.length)
751
+ current[high + 1] = BEYOND;
752
+ let rowMin = BEYOND;
753
+ for (let j = low;j <= high; j++) {
754
+ const cost = a[i - 1] === b[j - 1] ? 0 : 1;
755
+ let value = Math.min((previous[j] ?? BEYOND) + 1, (current[j - 1] ?? BEYOND) + 1, (previous[j - 1] ?? BEYOND) + cost);
756
+ if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) {
757
+ value = Math.min(value, (before[j - 2] ?? BEYOND) + 1);
758
+ }
759
+ current[j] = Math.min(value, BEYOND);
760
+ rowMin = Math.min(rowMin, value);
761
+ }
762
+ if (rowMin > limit)
763
+ return limit + 1;
764
+ [before, previous, current] = [previous, current, before];
765
+ }
766
+ return Math.min(previous[b.length] ?? BEYOND, limit + 1);
767
+ }
768
+ function words(path) {
769
+ return path.split(/[/\-_.]+/u).filter((word) => word.length > 0);
770
+ }
771
+ function wordAllowance(word) {
772
+ if (word.length < 4)
773
+ return 0;
774
+ return word.length < 8 ? 1 : 2;
775
+ }
776
+ function wordsMatch(missing, candidate) {
777
+ return missing.every((word) => {
778
+ const allowance = wordAllowance(word);
779
+ return candidate.some((other) => other === word || allowance > 0 && editDistance(word, other, allowance) <= allowance);
780
+ });
781
+ }
782
+ function candidate(path) {
783
+ const parts = words(path);
784
+ return {
785
+ path,
786
+ words: parts,
787
+ joined: parts.join(""),
788
+ last: path.slice(path.lastIndexOf("/") + 1)
789
+ };
790
+ }
791
+ function score(missing, page) {
792
+ if (page.path === missing.path)
793
+ return 0;
794
+ if (missing.joined.length >= 6 && missing.joined === page.joined)
795
+ return 0.1;
796
+ const longest = Math.max(missing.path.length, page.path.length);
797
+ const limit = Math.min(MAX_EDITS, Math.floor(longest / 4));
798
+ if (limit > 0 && wordsMatch(missing.words, page.words)) {
799
+ const distance = editDistance(missing.path, page.path, limit);
800
+ if (distance <= limit)
801
+ return distance / longest;
802
+ }
803
+ if (missing.last.length >= 6 && missing.last === page.last)
804
+ return 0.5;
805
+ const longer = missing.words.filter((word) => word.length >= 3);
806
+ if (longer.length >= 2 && longer.length === missing.words.length && longer.every((word) => page.words.includes(word)))
807
+ return 0.6;
808
+ return;
809
+ }
810
+ function suggestStatusRoute(pathname, routes) {
811
+ const normalized = normalizeStatusPath(pathname);
812
+ if (normalized === "/")
813
+ return;
814
+ const exactOnly = normalized.length < 5;
815
+ const missing = candidate(normalized);
816
+ let best;
817
+ for (const route of routes.slice(0, STATUS_PAGE_MAX_ROUTES)) {
818
+ if (!isSitePath(route.href))
819
+ continue;
820
+ const path = normalizeStatusPath(route.href);
821
+ if (path === "/" || exactOnly && path !== normalized)
822
+ continue;
823
+ const value = score(missing, candidate(path));
824
+ if (value === undefined)
825
+ continue;
826
+ if (best === undefined || value < best.score || value === best.score && (path.length < best.path.length || path.length === best.path.length && path < best.path)) {
827
+ best = {
828
+ route,
829
+ score: value,
830
+ path
831
+ };
832
+ }
833
+ }
834
+ return best?.route;
835
+ }
836
+ // src/status-page-html.ts
837
+ function renderStatusPageHtml(options = {}) {
838
+ const page = resolveStatusPage(options);
839
+ const level = options.titleLevel ?? 1;
840
+ const root = options.rootElement ?? "main";
841
+ const notFound = page.kind === "not-found";
842
+ const routes = notFound ? statusPageRoutesAttribute(page.routes) : undefined;
843
+ const next = page.next.length === 0 ? "" : [`<nav aria-labelledby="${STATUS_PAGE_NEXT_HEADING_ID}" class="hraness-status-page__next">`, `<h${level + 1} class="hraness-status-page__next-heading" id="${STATUS_PAGE_NEXT_HEADING_ID}">${escapeArticleHtml(page.nextHeading)}</h${level + 1}>`, '<ul class="hraness-status-page__next-list">', ...page.next.map((link) => [`<li><a class="hraness-status-page__next-link" href="${escapeArticleHtml(link.href)}">`, `<span class="hraness-status-page__next-label">${escapeArticleHtml(link.label)}</span>`, link.description === undefined ? "" : `<span class="hraness-status-page__next-description">${escapeArticleHtml(link.description)}</span>`, "</a></li>"].join("")), "</ul></nav>"].join("");
844
+ const agent = page.agentIndexHref === undefined ? "" : `<p class="hraness-status-page__agent">${STATUS_PAGE_AGENT_PREFIX} <a href="${escapeArticleHtml(page.agentIndexHref)}">${escapeArticleHtml(page.agentIndexHref)}</a></p>`;
845
+ return [`<${root} class="hraness-status-page"${routes === undefined ? "" : ` data-hraness-status-routes="${escapeArticleHtml(routes)}"`} data-kind="${page.kind}">`, '<div class="hraness-status-page__inner">', `<div aria-hidden="true" class="hraness-status-page__code"><span class="hraness-status-page__glyph">${escapeArticleHtml(page.glyph)}</span><canvas class="hraness-status-page__field"></canvas></div>`, `<h${level} class="hraness-status-page__title">${escapeArticleHtml(page.title)}</h${level}>`, `<p class="hraness-status-page__summary">${escapeArticleHtml(page.summary)}</p>`, notFound ? `<p class="hraness-status-page__hint" hidden="">${STATUS_PAGE_HINT_PREFIX} <a class="hraness-status-page__hint-link" href="/"></a>?</p>` : "", '<div class="hraness-status-page__actions">', `<a class="hraness-status-page__action hraness-foil" data-emphasis="primary" data-foil="" href="${escapeArticleHtml(page.primaryAction.href)}">${escapeArticleHtml(page.primaryAction.label)}</a>`, `<a class="hraness-status-page__back" hidden="" href="/">${STATUS_PAGE_BACK_LABEL}</a>`, "</div>", next, agent, "</div>", `</${root}>`].join("");
846
+ }
847
+ // src/relative-time.ts
848
+ var second = 1000;
849
+ var minute = 60 * second;
850
+ var hour = 60 * minute;
851
+ var day = 24 * hour;
852
+ var week = 7 * day;
853
+ var year = 365.2425 * day;
854
+ var month = year / 12;
855
+ var buckets = [{
856
+ unit: "second",
857
+ milliseconds: second,
858
+ limit: 60
859
+ }, {
860
+ unit: "minute",
861
+ milliseconds: minute,
862
+ limit: 60
863
+ }, {
864
+ unit: "hour",
865
+ milliseconds: hour,
866
+ limit: 24
867
+ }, {
868
+ unit: "day",
869
+ milliseconds: day,
870
+ limit: 7
871
+ }, {
872
+ unit: "week",
873
+ milliseconds: week,
874
+ limit: 4
875
+ }, {
876
+ unit: "month",
877
+ milliseconds: month,
878
+ limit: 12
879
+ }, {
880
+ unit: "year",
881
+ milliseconds: year,
882
+ limit: Number.POSITIVE_INFINITY
883
+ }];
884
+ var relativeTimeUnits = Object.freeze(buckets.map((bucket) => bucket.unit));
885
+ var maximumTime = 8640000000000000;
886
+ var isoDate = /^(\d{4})-(\d{2})-(\d{2})$/u;
887
+ var isoDateTime = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{1,9}))?)?(Z|[+-]\d{2}:\d{2})$/u;
888
+ function describe(value) {
889
+ if (typeof value === "string")
890
+ return JSON.stringify(value);
891
+ if (value instanceof Date)
892
+ return "an invalid Date";
893
+ return String(value);
894
+ }
895
+ function fromTime(time, label, original) {
896
+ if (!Number.isFinite(time) || Math.abs(time) > maximumTime) {
897
+ throw new RangeError(`${label} must be a valid instant; received ${describe(original)}.`);
898
+ }
899
+ return new Date(time);
900
+ }
901
+ function parseIsoString(value, label) {
902
+ const date = isoDate.exec(value);
903
+ const dateTime = date === null ? isoDateTime.exec(value) : null;
904
+ const parts = date ?? dateTime;
905
+ if (parts === null) {
906
+ throw new RangeError(`${label} must be an ISO 8601 date (YYYY-MM-DD) or a date-time with Z or an offset; received ${describe(value)}.`);
907
+ }
908
+ const [yearText, monthText, dayText, hourText = "00", minuteText = "00", secondText = "00", fraction = "", zone = "Z"] = parts.slice(1);
909
+ const fields = [yearText, monthText, dayText, hourText, minuteText, secondText].map(Number);
910
+ const [y, mo, d, h, mi, s] = fields;
911
+ const offsetHours = zone === "Z" ? 0 : Number(zone.slice(1, 3));
912
+ const offsetRest = zone === "Z" ? 0 : Number(zone.slice(4, 6));
913
+ const offsetMinutes = (zone.startsWith("-") ? -1 : 1) * (offsetHours * 60 + offsetRest);
914
+ const milliseconds = Number(fraction.padEnd(3, "0").slice(0, 3));
915
+ const wall = new Date(0);
916
+ wall.setUTCFullYear(y, mo - 1, d);
917
+ wall.setUTCHours(h, mi, s, milliseconds);
918
+ const valid = h < 24 && mi < 60 && s < 60 && offsetHours < 24 && offsetRest < 60 && wall.getUTCFullYear() === y && wall.getUTCMonth() === mo - 1 && wall.getUTCDate() === d;
919
+ if (!valid)
920
+ throw new RangeError(`${label} must name a real calendar instant; received ${describe(value)}.`);
921
+ return fromTime(wall.getTime() - offsetMinutes * minute, label, value);
922
+ }
923
+ function parseRelativeTimeInput(value, label = "time") {
924
+ if (value instanceof Date)
925
+ return fromTime(value.getTime(), label, value);
926
+ if (typeof value === "number")
927
+ return fromTime(value, label, value);
928
+ if (typeof value === "string")
929
+ return parseIsoString(value.trim(), label);
930
+ throw new TypeError(`${label} must be a Date, epoch milliseconds, or an ISO 8601 string.`);
931
+ }
932
+ function parseReference(value) {
933
+ if (value === undefined)
934
+ return new Date;
935
+ if (value instanceof Date || typeof value === "number")
936
+ return parseRelativeTimeInput(value, "now");
937
+ throw new TypeError("now must be a Date or epoch milliseconds.");
938
+ }
939
+ function parseNumeric(value) {
940
+ if (value === undefined)
941
+ return "auto";
942
+ if (value === "auto" || value === "always")
943
+ return value;
944
+ throw new TypeError(`numeric must be "auto" or "always"; received ${describe(value)}.`);
945
+ }
946
+ function parseLocale(value) {
947
+ if (value === undefined)
948
+ return;
949
+ if (typeof value !== "string" || value.trim() === "") {
950
+ throw new TypeError("locale must be a non-empty BCP 47 language tag.");
951
+ }
952
+ return value;
953
+ }
954
+ function resolveRelativeTime(differenceMilliseconds) {
955
+ if (!Number.isFinite(differenceMilliseconds)) {
956
+ throw new RangeError("The time difference must be a finite number of milliseconds.");
957
+ }
958
+ const magnitude = Math.abs(differenceMilliseconds);
959
+ const sign = differenceMilliseconds < 0 || Object.is(differenceMilliseconds, -0) ? -1 : 1;
960
+ for (const bucket of buckets) {
961
+ const amount = Math.round(magnitude / bucket.milliseconds);
962
+ if (amount < bucket.limit) {
963
+ return {
964
+ unit: bucket.unit,
965
+ value: sign * amount
966
+ };
967
+ }
968
+ }
969
+ throw new RangeError("No relative time unit matched.");
970
+ }
971
+ var formatters = new Map;
972
+ function formatterFor(locale, numeric) {
973
+ const key = `${locale ?? ""}\x00${numeric}`;
974
+ let formatter = formatters.get(key);
975
+ if (formatter === undefined) {
976
+ formatter = new Intl.RelativeTimeFormat(locale, {
977
+ numeric,
978
+ style: "long"
979
+ });
980
+ formatters.set(key, formatter);
981
+ }
982
+ return formatter;
983
+ }
984
+ function formatRelativeTime(target, options = {}) {
985
+ const instant = parseRelativeTimeInput(target, "target");
986
+ const reference = parseReference(options.now);
987
+ const numeric = parseNumeric(options.numeric);
988
+ const locale = parseLocale(options.locale);
989
+ const {
990
+ unit,
991
+ value
992
+ } = resolveRelativeTime(instant.getTime() - reference.getTime());
993
+ return formatterFor(locale, numeric).format(value, unit);
994
+ }
995
+
996
+ // src/index.ts
997
+ var colors = {
998
+ light: {
999
+ background: "#fbf6f2",
1000
+ foreground: "#201b19",
1001
+ muted: "#6b625d",
1002
+ faint: "#6b625d",
1003
+ grid: "#eaded8",
1004
+ line: "#bbaaa2",
1005
+ controlBorder: "#8f8f8f",
1006
+ surface: "#ffffff",
1007
+ surfaceRaised: "#f3ece8",
1008
+ surfaceHover: "#eaded8",
1009
+ card: "#ffffff",
1010
+ cardForeground: "#201b19",
1011
+ popover: "#ffffff",
1012
+ popoverForeground: "#201b19",
1013
+ primary: "#201b19",
1014
+ primaryForeground: "#fbf6f2",
1015
+ secondary: "#f3ece8",
1016
+ secondaryForeground: "#201b19",
1017
+ accent: "#eaded8",
1018
+ accentForeground: "#201b19",
1019
+ info: "#0d61ac",
1020
+ infoSoft: "#d8eaff",
1021
+ focus: "#0d61ac",
1022
+ scrim: "rgba(2, 2, 2, 0.44)",
1023
+ disabled: "#e8ded9",
1024
+ disabledForeground: "#717171",
1025
+ inverse: "#201b19",
1026
+ inverseForeground: "#fbf6f2",
1027
+ success: "#2d6a42",
1028
+ successSoft: "rgba(45, 106, 66, 0.12)",
1029
+ warning: "#785f28",
1030
+ warningSoft: "rgba(120, 95, 40, 0.12)",
1031
+ danger: "#9f3631",
1032
+ dangerSoft: "rgba(159, 54, 49, 0.12)"
1033
+ },
1034
+ dark: {
1035
+ background: "#000000",
1036
+ foreground: "#f2f2ed",
1037
+ muted: "#8f938c",
1038
+ faint: "#8f938c",
1039
+ grid: "#1c1e1b",
1040
+ line: "#5f645d",
1041
+ controlBorder: "#666666",
1042
+ surface: "#0d0e0c",
1043
+ surfaceRaised: "#161814",
1044
+ surfaceHover: "#1c1e1b",
1045
+ card: "#0d0e0c",
1046
+ cardForeground: "#f2f2ed",
1047
+ popover: "#161814",
1048
+ popoverForeground: "#f2f2ed",
1049
+ primary: "#f2f2ed",
1050
+ primaryForeground: "#0d0e0c",
1051
+ secondary: "#252820",
1052
+ secondaryForeground: "#f2f2ed",
1053
+ accent: "#1c1e1b",
1054
+ accentForeground: "#f2f2ed",
1055
+ info: "#6aa9ed",
1056
+ infoSoft: "#152d46",
1057
+ focus: "#6aa9ed",
1058
+ scrim: "rgba(0, 0, 0, 0.72)",
1059
+ disabled: "#262626",
1060
+ disabledForeground: "#777777",
1061
+ inverse: "#f2f2ed",
1062
+ inverseForeground: "#0d0e0c",
1063
+ success: "#76b38e",
1064
+ successSoft: "rgba(118, 179, 142, 0.12)",
1065
+ warning: "#c9ad74",
1066
+ warningSoft: "rgba(201, 173, 116, 0.12)",
1067
+ danger: "#e18982",
1068
+ dangerSoft: "rgba(225, 137, 130, 0.12)"
1069
+ }
1070
+ };
1071
+ var auroraColors = {
1072
+ light: {
1073
+ violet: "oklch(0.82 0.048 312)",
1074
+ rose: "oklch(0.85 0.044 12)",
1075
+ gold: "oklch(0.92 0.036 96)",
1076
+ mint: "oklch(0.9 0.036 172)",
1077
+ cyan: "oklch(0.84 0.042 236)"
1078
+ },
1079
+ dark: {
1080
+ violet: "oklch(0.58 0.045 312)",
1081
+ rose: "oklch(0.61 0.04 12)",
1082
+ gold: "oklch(0.69 0.035 96)",
1083
+ mint: "oklch(0.63 0.035 172)",
1084
+ cyan: "oklch(0.6 0.04 236)"
1085
+ }
1086
+ };
1087
+ var chromeColors = {
1088
+ light: {
1089
+ deep: "rgb(52 52 64)",
1090
+ shadow: "rgb(58 58 72)",
1091
+ mid: "rgb(92 92 106)",
1092
+ high: "rgb(88 88 100)",
1093
+ glint: "rgb(100 100 112)"
1094
+ },
1095
+ dark: {
1096
+ deep: "rgb(100 102 122)",
1097
+ shadow: "rgb(112 114 136)",
1098
+ mid: "rgb(166 168 190)",
1099
+ high: "rgb(158 160 182)",
1100
+ glint: "rgb(178 180 200)"
1101
+ }
1102
+ };
1103
+ var chromeGradientStops = {
1104
+ light: [[0, "rgb(52 52 64)"], [10, "rgb(88 88 100)"], [20, "rgb(58 58 72)"], [32, "rgb(100 100 112)"], [42, "rgb(64 64 78)"], [52, "rgb(92 92 106)"], [62, "rgb(54 54 68)"], [72, "rgb(86 86 100)"], [82, "rgb(56 56 70)"], [91, "rgb(80 80 94)"], [100, "rgb(60 60 74)"]],
1105
+ dark: [[0, "rgb(100 102 122)"], [10, "rgb(158 160 182)"], [20, "rgb(112 114 136)"], [32, "rgb(178 180 200)"], [42, "rgb(122 124 148)"], [52, "rgb(166 168 190)"], [62, "rgb(106 108 132)"], [72, "rgb(160 162 186)"], [82, "rgb(110 112 136)"], [91, "rgb(152 154 178)"], [100, "rgb(118 120 142)"]]
1106
+ };
1107
+ var spacing = [0, 4, 8, 12, 16, 20, 24, 32, 48, 64];
1108
+ var radius = {
1109
+ sharp: 0,
1110
+ sm: 4,
1111
+ md: 8,
1112
+ lg: 12,
1113
+ round: 999
1114
+ };
1115
+ var controlRadius = 16;
1116
+ var layout = {
1117
+ chromeInset: 8,
1118
+ edgeInset: 24
1119
+ };
1120
+ var siteThemes = {
1121
+ plain: {
1122
+ bodyClassName: "plain-site",
1123
+ footerClassName: "plain-footer",
1124
+ pageClassName: "plain-page"
1125
+ }
1126
+ };
1127
+ var interaction = {
1128
+ compactTarget: 40,
1129
+ minimumTarget: 48,
1130
+ controlHeight: 52,
1131
+ primaryControlHeight: 56,
1132
+ transportControlHeight: 64
1133
+ };
1134
+ var motion = {
1135
+ duration: {
1136
+ instant: 0,
1137
+ fast: 120,
1138
+ standard: 180,
1139
+ slow: 280
1140
+ },
1141
+ distance: {
1142
+ railEnter: 14,
1143
+ railExit: 10
1144
+ },
1145
+ easing: {
1146
+ standard: "cubic-bezier(0.2, 0, 0, 1)",
1147
+ emphasized: "cubic-bezier(0.16, 1, 0.3, 1)"
1148
+ }
1149
+ };
1150
+ var elevation = {
1151
+ none: "none",
1152
+ low: "0 1px 2px oklch(0 0 0 / 0.08)",
1153
+ raised: "0 8px 24px -12px oklch(0 0 0 / 0.22)",
1154
+ overlay: "0 18px 48px -18px oklch(0 0 0 / 0.32)"
1155
+ };
1156
+ var stacking = {
1157
+ chrome: 50,
1158
+ modal: 2000,
1159
+ tooltip: 3000,
1160
+ skipLink: 4000
1161
+ };
1162
+ var breakpoints = {
1163
+ compact: 480,
1164
+ medium: 768,
1165
+ wide: 1200,
1166
+ canvas: 1440
1167
+ };
1168
+ var iconography = {
1169
+ size: 20,
1170
+ strokeWidth: 1.5
1171
+ };
1172
+ var typeScale = {
1173
+ caption: 12,
1174
+ label: 14,
1175
+ body: 16,
1176
+ control: 16,
1177
+ controlGlyph: 20,
1178
+ heading: 24,
1179
+ title: 32,
1180
+ display: 56
1181
+ };
1182
+ var fontWeights = {
1183
+ regular: 450,
1184
+ medium: 550,
1185
+ bold: 700
1186
+ };
1187
+ var fontFamilies = {
1188
+ heading: "Nebula Sans",
1189
+ mono: "ui-monospace",
1190
+ text: "Nebula Sans"
1191
+ };
1192
+ var fontFallbacks = {
1193
+ mono: ["SFMono-Regular", "Menlo", "Monaco", "Consolas", "monospace"],
1194
+ text: ["system-ui", "-apple-system", "BlinkMacSystemFont", "Segoe UI", "sans-serif"]
1195
+ };
1196
+ var webTextStack = '"Nebula Sans", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif';
1197
+ var webMonoStack = 'ui-monospace, "SFMono-Regular", Menlo, Monaco, Consolas, monospace';
1198
+ var typography = {
1199
+ fontText: webTextStack,
1200
+ fontHeading: webTextStack,
1201
+ fontMono: webMonoStack,
1202
+ fontGeistMono: '"Geist Mono", ui-monospace, "SFMono-Regular", Menlo, Monaco, Consolas, monospace',
1203
+ fontSans: webTextStack
1204
+ };
1205
+ function themeFor(mode) {
1206
+ return colors[mode];
1207
+ }
1208
+
1209
+ export { designPalettes, designPaletteLabels, isDesignPalette, designPaletteSources, paletteColors, designThemes, defaultDesignTheme, designThemeStorageKey, isDesignTheme, normalizeDesignTheme, designThemeLabel, resolveDesignTheme, defaultDesignPalettePreference, designPaletteStorageKey, parseDesignPalettePreference, normalizeDesignPalettePreference, resolveDesignPalettePreference, getDesignPaletteTheme, escapeArticleHtml, renderArticleBylineHtml, renderArticleProvenanceHtml, renderArticleHtml, renderArticleSourcesHtml, renderArticleCalloutHtml, renderArticleRelatedHtml, renderArticleIndexHtml, STATUS_PAGE_MAX_NEXT, STATUS_PAGE_MAX_ROUTES, STATUS_PAGE_BACK_LABEL, STATUS_PAGE_HINT_PREFIX, STATUS_PAGE_NEXT_HEADING_ID, STATUS_PAGE_AGENT_PREFIX, resolveStatusPage, statusPageRoutesAttribute, parseStatusPageRoutes, normalizeStatusPath, suggestStatusRoute, renderStatusPageHtml, relativeTimeUnits, parseRelativeTimeInput, resolveRelativeTime, formatRelativeTime, colors, auroraColors, chromeColors, chromeGradientStops, spacing, radius, controlRadius, layout, siteThemes, interaction, motion, elevation, stacking, breakpoints, iconography, typeScale, fontWeights, fontFamilies, fontFallbacks, typography, themeFor };