retypeset-odyssey 0.1.0

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 (213) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +168 -0
  3. package/astro.config.ts +18 -0
  4. package/default-config.yaml +136 -0
  5. package/discover-collections.ts +160 -0
  6. package/integration.ts +394 -0
  7. package/package.json +105 -0
  8. package/patches/@qwik.dev__partytown@0.11.2.patch +98 -0
  9. package/public/_redirects +819 -0
  10. package/public/feeds/atom-style.xsl +105 -0
  11. package/public/feeds/rss-style.xsl +105 -0
  12. package/public/fonts/EarlySummer-VF-Split/00785494587e3487ac63a0e7e4fa30f0.woff2 +0 -0
  13. package/public/fonts/EarlySummer-VF-Split/08e5d941a4c76fad7b68e7a937ebb21f.woff2 +0 -0
  14. package/public/fonts/EarlySummer-VF-Split/1268e5072156188d601f1eeb4473655d.woff2 +0 -0
  15. package/public/fonts/EarlySummer-VF-Split/12a385475353c815d7a5add53ee51e37.woff2 +0 -0
  16. package/public/fonts/EarlySummer-VF-Split/12b11ca08223c65a21fc731d59dcfc11.woff2 +0 -0
  17. package/public/fonts/EarlySummer-VF-Split/16d6676d3cb645c520ee6df8a1f89afd.woff2 +0 -0
  18. package/public/fonts/EarlySummer-VF-Split/2912a75ffef95e7a5ae9e2b2311ad61d.woff2 +0 -0
  19. package/public/fonts/EarlySummer-VF-Split/298d96ea561e419a4104bc9fc18499ce.woff2 +0 -0
  20. package/public/fonts/EarlySummer-VF-Split/2a2c71acc17ec39f6780835899e53096.woff2 +0 -0
  21. package/public/fonts/EarlySummer-VF-Split/2a7e2d0e59d3f638074c50fab39fdef1.woff2 +0 -0
  22. package/public/fonts/EarlySummer-VF-Split/36931fc4370e1670ed76af5d3feccba2.woff2 +0 -0
  23. package/public/fonts/EarlySummer-VF-Split/3a68fdc792e4a9e0399a04e32d0cc2e3.woff2 +0 -0
  24. package/public/fonts/EarlySummer-VF-Split/4054d6a4d6b37719b51e0f71da6e7cd9.woff2 +0 -0
  25. package/public/fonts/EarlySummer-VF-Split/429cb25f825c3cbde6bfac5b36ae9675.woff2 +0 -0
  26. package/public/fonts/EarlySummer-VF-Split/42a9efc11298368ecdc1b85ab46f0b4f.woff2 +0 -0
  27. package/public/fonts/EarlySummer-VF-Split/432018d2bdc9df92a7662056eb2b1261.woff2 +0 -0
  28. package/public/fonts/EarlySummer-VF-Split/44a6fb782f2a01560faa0f95248b60ef.woff2 +0 -0
  29. package/public/fonts/EarlySummer-VF-Split/45367b060e8ba0aa2507e6b91b86620b.woff2 +0 -0
  30. package/public/fonts/EarlySummer-VF-Split/571db7564bda7c1a93542881b8976f4b.woff2 +0 -0
  31. package/public/fonts/EarlySummer-VF-Split/58d55eeef4cf455e86a1142b1f3110d3.woff2 +0 -0
  32. package/public/fonts/EarlySummer-VF-Split/59ea41e77309160a0f63cdc76a010202.woff2 +0 -0
  33. package/public/fonts/EarlySummer-VF-Split/5d19d9174e568db4755981aa2e4ab380.woff2 +0 -0
  34. package/public/fonts/EarlySummer-VF-Split/5e811eb3b4175ee93d7ec000bf4631c2.woff2 +0 -0
  35. package/public/fonts/EarlySummer-VF-Split/6268e0cd5d66d6fe05b331f259e7b9e4.woff2 +0 -0
  36. package/public/fonts/EarlySummer-VF-Split/6549844aa3d833ca06a68a8e839db465.woff2 +0 -0
  37. package/public/fonts/EarlySummer-VF-Split/714b459658a7321ceeb1e1386ce165c2.woff2 +0 -0
  38. package/public/fonts/EarlySummer-VF-Split/7511d97a469915013683eae06cb21cd9.woff2 +0 -0
  39. package/public/fonts/EarlySummer-VF-Split/7784b4ebe543d13f62f6f6e05beb0b2e.woff2 +0 -0
  40. package/public/fonts/EarlySummer-VF-Split/77c9bea70b3c6ab24e1497d5468c825b.woff2 +0 -0
  41. package/public/fonts/EarlySummer-VF-Split/789ebea9e81df623e930b86de98fbfab.woff2 +0 -0
  42. package/public/fonts/EarlySummer-VF-Split/885bb7ab0717e8a47fc17f953adcdbf1.woff2 +0 -0
  43. package/public/fonts/EarlySummer-VF-Split/896c58aff69a9a857764cee0663bc56d.woff2 +0 -0
  44. package/public/fonts/EarlySummer-VF-Split/8fb6fc01c59d1e3ad1910b58dec7f5e7.woff2 +0 -0
  45. package/public/fonts/EarlySummer-VF-Split/95be5462b91b9a0458797cdc89d94cb5.woff2 +0 -0
  46. package/public/fonts/EarlySummer-VF-Split/9a5b2724f983ca0fc0d5ff8d10c41396.woff2 +0 -0
  47. package/public/fonts/EarlySummer-VF-Split/9ffe17f9c0e4cc4356cb3f08ffdb9c6d.woff2 +0 -0
  48. package/public/fonts/EarlySummer-VF-Split/EarlySummer-VF-Subset.woff2 +0 -0
  49. package/public/fonts/EarlySummer-VF-Split/EarlySummerSerif License.txt +91 -0
  50. package/public/fonts/EarlySummer-VF-Split/a097ef49be62cd2565aca45600e1e3ac.woff2 +0 -0
  51. package/public/fonts/EarlySummer-VF-Split/a17a1ae6063088e5b3a48c06b816929a.woff2 +0 -0
  52. package/public/fonts/EarlySummer-VF-Split/a83fdcfc5ecf2f6996704b0c02758689.woff2 +0 -0
  53. package/public/fonts/EarlySummer-VF-Split/a8cf15ff9b71e59407d8406866ff6f99.woff2 +0 -0
  54. package/public/fonts/EarlySummer-VF-Split/af530ed51dd519e4456f8a5e259e908b.woff2 +0 -0
  55. package/public/fonts/EarlySummer-VF-Split/b195a8924915deec4aa9c3ec777cc93f.woff2 +0 -0
  56. package/public/fonts/EarlySummer-VF-Split/b4b6bb5df9239dd67b52ca858fd2a506.woff2 +0 -0
  57. package/public/fonts/EarlySummer-VF-Split/b7592e1e027923f19e0e55dfdac69668.woff2 +0 -0
  58. package/public/fonts/EarlySummer-VF-Split/b965859f69d8ccceaf0e2d6292afbcfb.woff2 +0 -0
  59. package/public/fonts/EarlySummer-VF-Split/bbe9333f1ff242bd96ecb23ff9e723b1.woff2 +0 -0
  60. package/public/fonts/EarlySummer-VF-Split/be758580e295339ea98f0240b9869f24.woff2 +0 -0
  61. package/public/fonts/EarlySummer-VF-Split/c07099e1d025617f6d40966986e1941b.woff2 +0 -0
  62. package/public/fonts/EarlySummer-VF-Split/c1b593dda62fdeb7dde3af02016da282.woff2 +0 -0
  63. package/public/fonts/EarlySummer-VF-Split/c89f0335910a68a0958f2846108370e8.woff2 +0 -0
  64. package/public/fonts/EarlySummer-VF-Split/ca49aa409fdedd3f2f894cd20a16640a.woff2 +0 -0
  65. package/public/fonts/EarlySummer-VF-Split/ccd4a28d2f63797e0183c87792e20b75.woff2 +0 -0
  66. package/public/fonts/EarlySummer-VF-Split/d2718da923fce8e7ea229d65e306e92c.woff2 +0 -0
  67. package/public/fonts/EarlySummer-VF-Split/d893e9b307d96041e9cfcbd03761b9f4.woff2 +0 -0
  68. package/public/fonts/EarlySummer-VF-Split/dafaedaee41b75e21479d4ff324b6a34.woff2 +0 -0
  69. package/public/fonts/EarlySummer-VF-Split/db392af65f1867e5fd580eed2195df99.woff2 +0 -0
  70. package/public/fonts/EarlySummer-VF-Split/dc7c73a9e5577143ccd11e05ab55cb39.woff2 +0 -0
  71. package/public/fonts/EarlySummer-VF-Split/de396881189f747eba67685298363242.woff2 +0 -0
  72. package/public/fonts/EarlySummer-VF-Split/df625b213228bba22a7733d4eff8f148.woff2 +0 -0
  73. package/public/fonts/EarlySummer-VF-Split/e6e60b384f220b893ef31a926ece829a.woff2 +0 -0
  74. package/public/fonts/EarlySummer-VF-Split/e6e8ce2c5972ab665630bb705383d0fb.woff2 +0 -0
  75. package/public/fonts/EarlySummer-VF-Split/e963c7ed7104c2d6d68fcb5f952fe2f5.woff2 +0 -0
  76. package/public/fonts/EarlySummer-VF-Split/e966b23b4cd7783f43e31032d41784f4.woff2 +0 -0
  77. package/public/fonts/EarlySummer-VF-Split/edaac57c3856ec13128f4c6c3e00975c.woff2 +0 -0
  78. package/public/fonts/EarlySummer-VF-Split/ee54e0d86edf068c6c9cbddb76a856fe.woff2 +0 -0
  79. package/public/fonts/EarlySummer-VF-Split/f612c78a5544ff2dd3e8296ac3e58344.woff2 +0 -0
  80. package/public/fonts/EarlySummer-VF-Split/f9e539bd9b7bf999c3da82f5403ec3b6.woff2 +0 -0
  81. package/public/fonts/EarlySummer-VF-Split/fa5863b923ac15993c52a619f699ee63.woff2 +0 -0
  82. package/public/fonts/EarlySummer-VF-Split/fc759e56ec6f6e6d3d4cb163d62fb557.woff2 +0 -0
  83. package/public/fonts/Font Subset List/CJK Common Characters.txt +7534 -0
  84. package/public/fonts/Font Subset List/EarlySummer Subset.txt +3 -0
  85. package/public/fonts/Font Subset List/Japanese Kana + Korean Letters.txt +6123 -0
  86. package/public/fonts/Font Subset List/Latin + Cyrillic + Greek + Arabic Glyphs.txt +121 -0
  87. package/public/fonts/Font Subset List/unicode_range.py +49 -0
  88. package/public/fonts/NotoSansSC-Bold.otf +0 -0
  89. package/public/fonts/NotoSansSC-Regular.otf +0 -0
  90. package/public/fonts/STIX-Italic-VF.woff2 +0 -0
  91. package/public/fonts/STIX-VF.woff2 +0 -0
  92. package/public/fonts/Snell-Black-SF.woff2 +0 -0
  93. package/public/fonts/Snell-Bold-SF.woff2 +0 -0
  94. package/public/giscus/theme-dark.css +208 -0
  95. package/public/giscus/theme-light.css +208 -0
  96. package/public/icons/favicon.svg +4 -0
  97. package/public/icons/og-logo.png +0 -0
  98. package/public/robots.txt +4 -0
  99. package/public/sounds/tap_01.wav +0 -0
  100. package/public/sounds/tap_02.wav +0 -0
  101. package/public/sounds/tap_03.wav +0 -0
  102. package/public/sounds/tap_04.wav +0 -0
  103. package/public/sounds/tap_05.wav +0 -0
  104. package/public/sounds/type_01.wav +0 -0
  105. package/public/sounds/type_02.wav +0 -0
  106. package/public/sounds/type_03.wav +0 -0
  107. package/public/sounds/type_04.wav +0 -0
  108. package/public/sounds/type_05.wav +0 -0
  109. package/scripts/apply-lqip.ts +276 -0
  110. package/scripts/format-posts.ts +105 -0
  111. package/scripts/migration/README.md +52 -0
  112. package/scripts/migration/migrate-hexo.ts +185 -0
  113. package/scripts/migration/validate-abbrlinks.ts +161 -0
  114. package/scripts/new-post.ts +52 -0
  115. package/scripts/seo/generate-legacy-redirects.ts +407 -0
  116. package/scripts/update-theme.ts +46 -0
  117. package/src/assets/icons/copy-check.svg +3 -0
  118. package/src/assets/icons/copy-icon.svg +4 -0
  119. package/src/assets/icons/go-back.svg +3 -0
  120. package/src/assets/icons/heading-anchor.svg +4 -0
  121. package/src/assets/icons/lang-en.svg +3 -0
  122. package/src/assets/icons/lang-ja.svg +5 -0
  123. package/src/assets/icons/lang-zh.svg +5 -0
  124. package/src/assets/icons/language-switcher.svg +3 -0
  125. package/src/assets/icons/pin-icon.svg +3 -0
  126. package/src/assets/icons/search-icon.svg +3 -0
  127. package/src/assets/icons/theme-toggle.svg +3 -0
  128. package/src/assets/icons/toc-icon.svg +3 -0
  129. package/src/assets/icons/top-icon.svg +3 -0
  130. package/src/assets/lqip-map.json +10 -0
  131. package/src/components/Button.astro +152 -0
  132. package/src/components/CategoryList.astro +66 -0
  133. package/src/components/Comment/Giscus.astro +119 -0
  134. package/src/components/Comment/Index.astro +30 -0
  135. package/src/components/Comment/Twikoo.astro +114 -0
  136. package/src/components/Comment/Waline.astro +149 -0
  137. package/src/components/FloatingButtons.astro +101 -0
  138. package/src/components/Footer.astro +74 -0
  139. package/src/components/Header.astro +62 -0
  140. package/src/components/JournalList.astro +56 -0
  141. package/src/components/Navbar.astro +69 -0
  142. package/src/components/NoteList.astro +56 -0
  143. package/src/components/Pagination.astro +267 -0
  144. package/src/components/PostDate.astro +80 -0
  145. package/src/components/PostList.astro +87 -0
  146. package/src/components/SearchModal.astro +340 -0
  147. package/src/components/TagList.astro +135 -0
  148. package/src/components/Widgets/BackButton.astro +43 -0
  149. package/src/components/Widgets/CodeCopyButton.astro +47 -0
  150. package/src/components/Widgets/GithubCard.astro +110 -0
  151. package/src/components/Widgets/ImageZoom.astro +135 -0
  152. package/src/components/Widgets/MediaEmbed.astro +127 -0
  153. package/src/components/Widgets/SoundEffect.astro +179 -0
  154. package/src/components/Widgets/TOC.astro +198 -0
  155. package/src/config-schema.ts +164 -0
  156. package/src/config.ts +127 -0
  157. package/src/config.ts.example +205 -0
  158. package/src/content/about/_example-about-en.md +6 -0
  159. package/src/content/about/about-en.md +21 -0
  160. package/src/content/about/about-ja.md +21 -0
  161. package/src/content/about/about-zh.md +24 -0
  162. package/src/content.config.ts +247 -0
  163. package/src/env.d.ts +25 -0
  164. package/src/i18n/config.ts +65 -0
  165. package/src/i18n/lang.ts +70 -0
  166. package/src/i18n/path.ts +160 -0
  167. package/src/i18n/ui.ts +214 -0
  168. package/src/layouts/Head.astro +203 -0
  169. package/src/layouts/Layout.astro +69 -0
  170. package/src/pages/404.astro +20 -0
  171. package/src/pages/[...lang]/[...page].astro +48 -0
  172. package/src/pages/[...lang]/about.astro +28 -0
  173. package/src/pages/[...lang]/atom.xml.ts +14 -0
  174. package/src/pages/[...lang]/categories/index.astro +35 -0
  175. package/src/pages/[...lang]/journals/[slug].astro +89 -0
  176. package/src/pages/[...lang]/journals/index.astro +55 -0
  177. package/src/pages/[...lang]/journals/page/[page].astro +66 -0
  178. package/src/pages/[...lang]/notes/[slug].astro +88 -0
  179. package/src/pages/[...lang]/notes/index.astro +55 -0
  180. package/src/pages/[...lang]/notes/page/[page].astro +66 -0
  181. package/src/pages/[...lang]/posts/[slug].astro +101 -0
  182. package/src/pages/[...lang]/rss.xml.ts +14 -0
  183. package/src/pages/[...lang]/search.astro +65 -0
  184. package/src/pages/[...lang]/tags/[tag].astro +53 -0
  185. package/src/pages/[...lang]/tags/index.astro +36 -0
  186. package/src/pages/_dynamic/list.astro +101 -0
  187. package/src/pages/_dynamic/slug.astro +100 -0
  188. package/src/pages/og/[...image].ts +114 -0
  189. package/src/pages/robots.txt.ts +20 -0
  190. package/src/plugins/rehype-code-copy-button.mjs +82 -0
  191. package/src/plugins/rehype-external-links.mjs +18 -0
  192. package/src/plugins/rehype-heading-anchor.mjs +55 -0
  193. package/src/plugins/rehype-image-processor.mjs +77 -0
  194. package/src/plugins/remark-container-directives.mjs +135 -0
  195. package/src/plugins/remark-leaf-directives.mjs +184 -0
  196. package/src/plugins/remark-reading-time.mjs +11 -0
  197. package/src/styles/comment.css +205 -0
  198. package/src/styles/extension.css +180 -0
  199. package/src/styles/font.css +111 -0
  200. package/src/styles/global.css +91 -0
  201. package/src/styles/lqip.css +71 -0
  202. package/src/styles/markdown.css +276 -0
  203. package/src/styles/transition.css +173 -0
  204. package/src/types/global.d.ts +22 -0
  205. package/src/types/index.d.ts +111 -0
  206. package/src/utils/cache.ts +32 -0
  207. package/src/utils/content.ts +819 -0
  208. package/src/utils/description.ts +147 -0
  209. package/src/utils/dynamic-collections.ts +155 -0
  210. package/src/utils/feed.ts +238 -0
  211. package/src/utils/page.ts +107 -0
  212. package/tsconfig.json +13 -0
  213. package/uno.config.ts +75 -0
@@ -0,0 +1,276 @@
1
+ /*!
2
+ * Markdown Styles
3
+ * Project: https://github.com/sivan/heti
4
+ * Source: https://unpkg.com/heti/umd/heti.min.css
5
+ */
6
+
7
+ /* Global Styles */
8
+ .heti {
9
+ --at-apply: 'break-words leading-normal hyphens-auto cjk:tracking-wide';
10
+ }
11
+
12
+ /* Customized Post Title */
13
+ .heti .post-title {
14
+ --at-apply: 'mb-2 mt-0 text-8.5 font-bold lg:text-9';
15
+ }
16
+
17
+ /* Headings */
18
+ .heti :where(h1, h2, h3, h4, h5, h6) {
19
+ --at-apply: 'mb-4 mt-1.5em scroll-mt-20 font-semibold';
20
+ }
21
+ .heti :where(h1) {
22
+ --at-apply: 'text-7 c-primary';
23
+ }
24
+ .heti :where(h2) {
25
+ --at-apply: 'text-6 c-primary';
26
+ }
27
+ .heti :where(h3) {
28
+ --at-apply: 'text-5';
29
+ }
30
+ .heti :where(h4) {
31
+ --at-apply: 'text-4.5';
32
+ }
33
+ .heti :where(h5) {
34
+ --at-apply: 'text-4';
35
+ }
36
+ .heti :where(h6) {
37
+ --at-apply: 'font-normal';
38
+ }
39
+ .heti :where(h1, h2, h3) {
40
+ --at-apply: 'text-balance leading-1.33em cjk:text-pretty cjk:tracking-wider';
41
+ }
42
+ .heti :where(h1 + h2, h2 + h3, h3 + h4, h4 + h5, h5 + h6) {
43
+ --at-apply: 'mt-4';
44
+ }
45
+
46
+ /* Paragraphs */
47
+ .heti :where(p:not(.no-heti):not(.no-heti *)) {
48
+ --at-apply: 'mb-4 text-pretty cjk:text-justify';
49
+ }
50
+
51
+ /* Links */
52
+ .heti :where(a:not(.no-heti):not(.no-heti *)) {
53
+ --at-apply: 'font-semibold tracking-normal underline underline-0.075em decoration-secondary/80 underline-offset-0.1em cjk:break-all';
54
+ --at-apply: 'transition-colors ease-out hover:(c-primary decoration-primary/80) lg:underline-0.1em';
55
+ }
56
+
57
+ /* Images */
58
+ .heti :where(img:not(.no-heti):not(.no-heti *)) {
59
+ --at-apply: 'mx-auto cursor-zoom-in';
60
+ }
61
+ .heti :where(img:not(figure img):not(.no-heti):not(.no-heti *)) {
62
+ --at-apply: 'my-6';
63
+ }
64
+ .heti :where(figure) {
65
+ --at-apply: 'my-6 w-full';
66
+ }
67
+ .heti :where(figcaption) {
68
+ --at-apply: 'mt-2.5 text-center text-sm c-secondary/80';
69
+ }
70
+ .heti :is(h1, h2, h3, h4, h5, h6, img, figure) + :is(img, figure) {
71
+ --at-apply: 'mt-4';
72
+ }
73
+ .heti :is(img, figure):has(+ :is(img, figure)) {
74
+ --at-apply: 'mb-4';
75
+ }
76
+
77
+ /* Code Blocks */
78
+ .heti :where(pre) {
79
+ --at-apply: 'overflow-auto uno-round-border px-4 py-3 bg-secondary/5!';
80
+ scrollbar-width: thin;
81
+ scrollbar-color: oklch(var(--un-preset-theme-colors-secondary) / 0) transparent;
82
+ transition: scrollbar-color 0.3s ease-out;
83
+ }
84
+ .heti :where(pre):hover {
85
+ scrollbar-color: oklch(var(--un-preset-theme-colors-secondary) / 0.15) transparent;
86
+ }
87
+ .heti pre code {
88
+ --at-apply: 'border-none bg-transparent p-0';
89
+ }
90
+ html.dark .heti pre span {
91
+ --at-apply: 'text-[var(--shiki-dark)]!';
92
+ }
93
+ .heti .code-block-wrapper {
94
+ --at-apply: 'my-6 relative';
95
+ }
96
+ .heti :is(h1, h2, h3, h4, h5, h6, .code-block-wrapper) + .code-block-wrapper {
97
+ --at-apply: 'mt-4';
98
+ }
99
+ .heti .code-block-wrapper:has(+ .code-block-wrapper) {
100
+ --at-apply: 'mb-4';
101
+ }
102
+
103
+ /* Inline Code */
104
+ .heti :where(code) {
105
+ --at-apply: 'uno-round-border bg-secondary/5 px-0.4em py-0.15em text-0.85em tracking-normal cjk:break-all';
106
+ counter-reset: line;
107
+ }
108
+ .heti code span.line {
109
+ --at-apply: 'relative pl-8';
110
+ }
111
+ .heti code span.line::before {
112
+ --at-apply: 'absolute left-0 w-4 c-secondary/40 leading-1.9em';
113
+ content: counter(line);
114
+ counter-increment: line;
115
+ direction: rtl;
116
+ }
117
+
118
+ /* Blockquotes */
119
+ .heti :where(blockquote) {
120
+ --at-apply: 'my-6 border-l-4 border-secondary/25 border-solid px-4 py-0.5 c-secondary/80';
121
+ }
122
+ .heti blockquote[class*="admonition-"] {
123
+ --at-apply: 'py-1.5 c-secondary';
124
+ }
125
+ .heti blockquote blockquote {
126
+ --at-apply: 'py-0';
127
+ }
128
+ .heti blockquote > :first-child {
129
+ --at-apply: 'mt-0';
130
+ }
131
+ .heti blockquote > :last-child {
132
+ --at-apply: 'mb-0';
133
+ }
134
+ .heti :is(h1, h2, h3, h4, h5, h6, blockquote) + blockquote {
135
+ --at-apply: 'mt-4';
136
+ }
137
+ .heti blockquote:has(+ blockquote) {
138
+ --at-apply: 'mb-4';
139
+ }
140
+
141
+ /* Tables */
142
+ .heti :where(table) {
143
+ --at-apply: 'my-6 box-border block max-w-full table-fixed overflow-x-auto';
144
+ scrollbar-width: thin;
145
+ scrollbar-color: oklch(var(--un-preset-theme-colors-secondary) / 0) transparent;
146
+ transition: scrollbar-color 0.3s ease-out;
147
+ }
148
+ .heti :where(table):hover {
149
+ scrollbar-color: oklch(var(--un-preset-theme-colors-secondary) / 0.15) transparent;
150
+ }
151
+ .heti :where(th, td) {
152
+ --at-apply: 'border-b border-b-secondary/25 px-3 pb-1.5';
153
+ }
154
+ .heti tr :where(td:first-child, th:first-child) {
155
+ --at-apply: 'pl-0';
156
+ }
157
+ .heti tr :where(td:last-child, th:last-child) {
158
+ --at-apply: 'pr-0';
159
+ }
160
+ .heti :where(td) {
161
+ --at-apply: 'pt-1.5';
162
+ }
163
+ .heti tr:last-child :where(td) {
164
+ --at-apply: 'border-b-0';
165
+ }
166
+ .heti :is(h1, h2, h3, h4, h5, h6, table) + table {
167
+ --at-apply: 'mt-4';
168
+ }
169
+ .heti table:has(+ table) {
170
+ --at-apply: 'mb-4';
171
+ }
172
+
173
+ /* Lists */
174
+ .heti :where(ul, ol) {
175
+ --at-apply: 'my-6 pl-2em';
176
+ }
177
+ .heti :where(ul, ol) :where(ul, ol) {
178
+ --at-apply: 'mb-0.25em mt-0';
179
+ }
180
+ .heti :where(ul) {
181
+ --at-apply: 'list-disc';
182
+ }
183
+ .heti :where(ol) {
184
+ --at-apply: 'list-decimal';
185
+ }
186
+ .heti :where(ul, ol) :where(ul) {
187
+ --at-apply: 'list-circle';
188
+ }
189
+ .heti :where(ul, ol) :where(ul, ol) :where(ul) {
190
+ --at-apply: 'list-square';
191
+ }
192
+ .heti :where(li) {
193
+ --at-apply: 'mt-0.25em list-unset';
194
+ }
195
+ .heti :is(h1, h2, h3, h4, h5, h6, ul, ol) + :is(ul, ol) {
196
+ --at-apply: 'mt-4';
197
+ }
198
+ .heti :is(ul, ol):has(+ :is(ul, ol)) {
199
+ --at-apply: 'mb-4';
200
+ }
201
+
202
+ /* Superscript and Subscript >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
203
+ .heti :where(sub, sup) {
204
+ --at-apply: 'relative mx-0.1em align-baseline text-0.75em';
205
+ }
206
+ .heti :where(sub) {
207
+ --at-apply: 'bottom--0.25em';
208
+ }
209
+ .heti :where(sup) {
210
+ --at-apply: 'top--0.5em';
211
+ }
212
+
213
+ /* Abbreviations */
214
+ .heti :where(abbr[title]) {
215
+ --at-apply: 'cursor-help border-b-1 border-secondary border-dotted pb-0.25 no-underline';
216
+ }
217
+
218
+ /* Wavy Underline */
219
+ .heti :where(u) {
220
+ --at-apply: 'underline decoration-red-400 underline-offset-0.25em decoration-wavy';
221
+ }
222
+ html.dark .heti :where(u) {
223
+ --at-apply: 'decoration-red-400/60';
224
+ }
225
+
226
+ /* Keyboard Input */
227
+ .heti :where(kbd) {
228
+ --at-apply: 'inline-block px-0.4em py-0.3em text-0.85em font-bold leading-none tracking-normal';
229
+ --at-apply: 'uno-round-border border-secondary/40 c-secondary';
230
+ }
231
+
232
+ /* Highlighted Text */
233
+ .heti :where(mark) {
234
+ --at-apply: 'bg-highlight py-0.65 text-inherit';
235
+ }
236
+
237
+ /* Footnotes */
238
+ .heti :where(sub, sup) :where(a) {
239
+ --at-apply: 'no-underline';
240
+ }
241
+ .heti :where(sup):target,
242
+ .heti :where(sup) a:target {
243
+ --at-apply: 'bg-highlight';
244
+ }
245
+ .heti .data-footnote-backref {
246
+ --at-apply: 'font-serif no-underline';
247
+ }
248
+
249
+ /* Horizontal Rules */
250
+ .heti :where(hr) {
251
+ --at-apply: 'mb-10.5 mt-14.5 h-auto border-none text-center';
252
+ }
253
+ .heti :where(hr)::before {
254
+ --at-apply: 'whitespace-pre text-6 c-secondary/25 font-serif';
255
+ content: "* * *";
256
+ }
257
+
258
+ /* Bold */
259
+ .heti :where(b, strong) {
260
+ --at-apply: 'font-semibold';
261
+ }
262
+
263
+ /* Italic */
264
+ .heti :where(em) {
265
+ --at-apply: 'italic';
266
+ }
267
+
268
+ /* Cite */
269
+ .heti :where(cite) {
270
+ --at-apply: 'cjk:not-italic';
271
+ }
272
+
273
+ /* Quotes */
274
+ .heti :where(q:is(:lang(zh), :lang(ja), :lang(ko))) {
275
+ quotes: "「" "」" "『" "』";
276
+ }
@@ -0,0 +1,173 @@
1
+ /* View Transition */
2
+ @keyframes reveal {
3
+ from {
4
+ clip-path: inset(var(--from));
5
+ }
6
+ }
7
+
8
+ ::view-transition-new(theme-toggle-transition) {
9
+ z-index: 99;
10
+ clip-path: inset(0 0 0 0);
11
+ animation: reveal 0.7s cubic-bezier(0.4, 0, 0.2, 1);
12
+ }
13
+ ::view-transition-old(theme-toggle-transition) {
14
+ z-index: -1;
15
+ animation: none;
16
+ }
17
+
18
+ html.dark {
19
+ --from: 0 0 100% 0;
20
+ }
21
+ html:not(.dark) {
22
+ --from: 100% 0 0 0;
23
+ }
24
+
25
+ /* Disable animations for special elements during theme switching */
26
+ html[data-theme-changing] [data-disable-theme-toggle-transition] {
27
+ view-transition-name: none !important;
28
+ }
29
+
30
+ /* Content Progressive Animation >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
31
+ @keyframes fadeInUp {
32
+ from {
33
+ opacity: 0;
34
+ transform: translateY(3rem);
35
+ }
36
+ to {
37
+ opacity: 1;
38
+ transform: translateY(0);
39
+ }
40
+ }
41
+
42
+ @media (max-width: 1535px) {
43
+ #toc-container {
44
+ opacity: 0;
45
+ animation: fadeInUp 0.5s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
46
+ animation-delay: 0.1s;
47
+ }
48
+ }
49
+
50
+ @media (min-width: 1024px) {
51
+ #post-date {
52
+ opacity: 0;
53
+ animation: fadeInUp 0.5s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
54
+ animation-delay: 0.1s;
55
+ }
56
+ }
57
+
58
+ #post-content > * {
59
+ opacity: 0;
60
+ animation: fadeInUp 0.5s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
61
+ }
62
+
63
+ #post-content > *:nth-child(1) { animation-delay: 0.15s; }
64
+ #post-content > *:nth-child(2) { animation-delay: 0.2s; }
65
+ #post-content > *:nth-child(3) { animation-delay: 0.25s; }
66
+ #post-content > *:nth-child(4) { animation-delay: 0.3s; }
67
+ #post-content > *:nth-child(5) { animation-delay: 0.35s; }
68
+ #post-content > *:nth-child(6) { animation-delay: 0.4s; }
69
+ #post-content > *:nth-child(7) { animation-delay: 0.45s; }
70
+ #post-content > *:nth-child(8) { animation-delay: 0.5s; }
71
+ #post-content > *:nth-child(9) { animation-delay: 0.55s; }
72
+ #post-content > *:nth-child(10) { animation-delay: 0.6s; }
73
+ #post-content > *:nth-child(11) { animation-delay: 0.65s; }
74
+ #post-content > *:nth-child(12) { animation-delay: 0.7s; }
75
+ #post-content > *:nth-child(13) { animation-delay: 0.75s; }
76
+ #post-content > *:nth-child(14) { animation-delay: 0.8s; }
77
+ #post-content > *:nth-child(15) { animation-delay: 0.85s; }
78
+ #post-content > *:nth-child(n+16) { animation-delay: 0.9s; }
79
+
80
+ @media (max-width: 767px) {
81
+ #post-content > *:nth-child(n+8) {
82
+ opacity: 1;
83
+ transform: translateY(0);
84
+ animation: none;
85
+ }
86
+ }
87
+
88
+ /* TOC Progressive Animation >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
89
+ @keyframes fadeInUpMini {
90
+ from {
91
+ opacity: 0;
92
+ transform: translateY(1.5rem);
93
+ }
94
+ to {
95
+ opacity: 1;
96
+ transform: translateY(0);
97
+ }
98
+ }
99
+
100
+ @media (min-width: 1535px) {
101
+ #toc-desktop-icon {
102
+ opacity: 0;
103
+ animation: fadeInUpMini 0.5s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
104
+ animation-delay: 0.175s;
105
+ }
106
+
107
+ #toc-links-list > * {
108
+ opacity: 0;
109
+ animation: fadeInUp 0.5s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
110
+ }
111
+
112
+
113
+ #toc-links-list > *:nth-child(1) { animation-delay: 0.175s; }
114
+ #toc-links-list > *:nth-child(2) { animation-delay: 0.2s; }
115
+ #toc-links-list > *:nth-child(3) { animation-delay: 0.225s; }
116
+ #toc-links-list > *:nth-child(4) { animation-delay: 0.25s; }
117
+ #toc-links-list > *:nth-child(5) { animation-delay: 0.275s; }
118
+ #toc-links-list > *:nth-child(6) { animation-delay: 0.3s; }
119
+ #toc-links-list > *:nth-child(7) { animation-delay: 0.325s; }
120
+ #toc-links-list > *:nth-child(8) { animation-delay: 0.35s; }
121
+ #toc-links-list > *:nth-child(9) { animation-delay: 0.375s; }
122
+ #toc-links-list > *:nth-child(10) { animation-delay: 0.4s; }
123
+ #toc-links-list > *:nth-child(11) { animation-delay: 0.425s; }
124
+ #toc-links-list > *:nth-child(12) { animation-delay: 0.45s; }
125
+ #toc-links-list > *:nth-child(13) { animation-delay: 0.475s; }
126
+ #toc-links-list > *:nth-child(14) { animation-delay: 0.5s; }
127
+ #toc-links-list > *:nth-child(15) { animation-delay: 0.525s; }
128
+ #toc-links-list > *:nth-child(16) { animation-delay: 0.55s; }
129
+ #toc-links-list > *:nth-child(17) { animation-delay: 0.575s; }
130
+ #toc-links-list > *:nth-child(18) { animation-delay: 0.6s; }
131
+ #toc-links-list > *:nth-child(n+19) { animation-delay: 0.625s; }
132
+ }
133
+
134
+ /* Back Button Animation >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
135
+ @keyframes fadeInLeft {
136
+ from {
137
+ opacity: 0;
138
+ transform: translateX(0.5rem);
139
+ }
140
+ to {
141
+ opacity: 1;
142
+ transform: translateX(0);
143
+ }
144
+ }
145
+
146
+ @media (min-width: 1024px) {
147
+ #back-button {
148
+ opacity: 0;
149
+ animation: fadeInLeft 0.5s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
150
+ animation-delay: 0.2s;
151
+ }
152
+ }
153
+
154
+ /* Fallback Transition >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
155
+ html.reduce-motion {
156
+ --at-apply: 'transition-colors duration-300 ease-out';
157
+
158
+ .highlight-hover,
159
+ .highlight-static {
160
+ --at-apply: 'transition-inherit';
161
+ }
162
+
163
+ #toc-container,
164
+ #post-date,
165
+ #post-content > *,
166
+ #toc-desktop-icon,
167
+ #toc-links-list > *,
168
+ #back-button {
169
+ opacity: 1;
170
+ transform: translate(0);
171
+ animation: none;
172
+ }
173
+ }
@@ -0,0 +1,22 @@
1
+ import type { AttributifyAttributes } from '@unocss/preset-attributify'
2
+
3
+ declare global {
4
+ namespace astroHTML.JSX {
5
+ interface HTMLAttributes extends AttributifyAttributes {}
6
+ }
7
+
8
+ interface Window {
9
+ webkitAudioContext: typeof AudioContext
10
+ }
11
+ interface Document {
12
+ startViewTransition: (updateCallback: () => void) => ViewTransition
13
+ }
14
+
15
+ interface ViewTransition {
16
+ finished: Promise<void>
17
+ ready: Promise<void>
18
+ updateCallbackDone: Promise<void>
19
+ }
20
+ }
21
+
22
+ export {}
@@ -0,0 +1,111 @@
1
+ import type { CollectionEntry } from 'astro:content'
2
+ import type { Language } from '@/i18n/config'
3
+
4
+ export type Post = CollectionEntry<'posts'> & {
5
+ remarkPluginFrontmatter: {
6
+ minutes: number
7
+ }
8
+ }
9
+
10
+ export type Note = CollectionEntry<'notes'> & {
11
+ remarkPluginFrontmatter: {
12
+ minutes: number
13
+ }
14
+ }
15
+
16
+ export type Journal = CollectionEntry<'journals'> & {
17
+ remarkPluginFrontmatter: {
18
+ minutes: number
19
+ }
20
+ }
21
+
22
+ // The runtime shape is now derived from the Zod schema in config-schema.ts.
23
+ // The interface below is kept for editor tooling / docs and is structurally
24
+ // compatible with the inferred type.
25
+ export interface ThemeConfig {
26
+ site: {
27
+ title: string
28
+ subtitle: string
29
+ description: string
30
+ i18nTitle: boolean
31
+ author: string
32
+ url: string
33
+ base: string
34
+ favicon: string
35
+ }
36
+ color: {
37
+ mode: 'light' | 'dark' | 'auto'
38
+ light: {
39
+ primary: string
40
+ secondary: string
41
+ background: string
42
+ highlight: string
43
+ }
44
+ dark: {
45
+ primary: string
46
+ secondary: string
47
+ background: string
48
+ highlight: string
49
+ }
50
+ }
51
+ global: {
52
+ locale: Language
53
+ moreLocales: Language[]
54
+ fontStyle: 'sans' | 'serif'
55
+ dateFormat: 'YYYY-MM-DD' | 'MM-DD-YYYY' | 'DD-MM-YYYY' | 'MMM D YYYY' | 'D MMM YYYY'
56
+ toc: boolean
57
+ katex: boolean
58
+ reduceMotion: boolean
59
+ }
60
+ comment: {
61
+ enabled: boolean
62
+ giscus?: {
63
+ repo?: string
64
+ repoId?: string
65
+ category?: string
66
+ categoryId?: string
67
+ mapping?: 'pathname' | 'url' | 'title' | 'og:title'
68
+ strict?: '0' | '1'
69
+ reactionsEnabled?: '0' | '1'
70
+ emitMetadata?: '0' | '1'
71
+ inputPosition?: 'top' | 'bottom'
72
+ }
73
+ twikoo?: {
74
+ envId?: string
75
+ }
76
+ waline?: {
77
+ serverURL?: string
78
+ emoji?: string[]
79
+ search?: boolean
80
+ imageUploader?: boolean
81
+ }
82
+ }
83
+ seo?: {
84
+ twitterID?: string
85
+ verification?: {
86
+ google?: string
87
+ bing?: string
88
+ yandex?: string
89
+ baidu?: string
90
+ }
91
+ googleAnalyticsID?: string
92
+ umamiAnalyticsID?: string
93
+ follow?: {
94
+ feedID?: string
95
+ userID?: string
96
+ }
97
+ apiflashKey?: string
98
+ }
99
+ footer: {
100
+ links: {
101
+ name: string
102
+ url: string
103
+ }[]
104
+ startYear: number
105
+ }
106
+ preload?: {
107
+ imageHostURL?: string
108
+ customGoogleAnalyticsJS?: string
109
+ customUmamiAnalyticsJS?: string
110
+ }
111
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Memoizes an async function, caching results by arguments
3
+ *
4
+ * @param fn - The async function to memoize
5
+ * @returns Memoized function that caches results
6
+ */
7
+ export function memoize<Args extends any[], T>(
8
+ fn: (...args: Args) => Promise<T>,
9
+ ): (...args: Args) => Promise<T> {
10
+ const cache = new Map<string, Promise<T>>()
11
+
12
+ return async (...args: Args): Promise<T> => {
13
+ // Generate cache key from function arguments
14
+ const key = JSON.stringify(args)
15
+
16
+ // Return cached promise if it exists
17
+ if (cache.has(key)) {
18
+ return cache.get(key)!
19
+ }
20
+
21
+ // Execute the original function and cache the promise
22
+ const promise = fn(...args)
23
+ cache.set(key, promise)
24
+
25
+ // Remove failed promises from cache to allow retry
26
+ promise.catch(() => {
27
+ cache.delete(key)
28
+ })
29
+
30
+ return promise
31
+ }
32
+ }