@jant/core 0.3.23 → 0.3.25

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 (248) hide show
  1. package/dist/app.js +50 -26
  2. package/dist/db/schema.js +72 -47
  3. package/dist/i18n/locales/en.js +1 -1
  4. package/dist/i18n/locales/zh-Hans.js +1 -1
  5. package/dist/i18n/locales/zh-Hant.js +1 -1
  6. package/dist/index.js +5 -11
  7. package/dist/lib/constants.js +2 -4
  8. package/dist/lib/excerpt.js +76 -0
  9. package/dist/lib/feed.js +18 -7
  10. package/dist/lib/nav-reorder.js +1 -1
  11. package/dist/lib/navigation.js +30 -6
  12. package/dist/lib/pagination.js +44 -0
  13. package/dist/lib/render.js +7 -11
  14. package/dist/lib/schemas.js +80 -38
  15. package/dist/lib/theme.js +4 -4
  16. package/dist/lib/time.js +56 -1
  17. package/dist/lib/timeline.js +95 -0
  18. package/dist/lib/view.js +61 -72
  19. package/dist/routes/api/collections.js +124 -0
  20. package/dist/routes/api/nav-items.js +104 -0
  21. package/dist/routes/api/pages.js +91 -0
  22. package/dist/routes/api/posts.js +27 -33
  23. package/dist/routes/api/search.js +4 -5
  24. package/dist/routes/api/settings.js +68 -0
  25. package/dist/routes/api/upload.js +13 -13
  26. package/dist/routes/compose.js +48 -0
  27. package/dist/routes/dash/collections.js +24 -42
  28. package/dist/routes/dash/index.js +3 -3
  29. package/dist/routes/dash/media.js +2 -2
  30. package/dist/routes/dash/pages.js +440 -106
  31. package/dist/routes/dash/posts.js +27 -37
  32. package/dist/routes/dash/redirects.js +2 -2
  33. package/dist/routes/dash/settings.js +79 -5
  34. package/dist/routes/feed/rss.js +4 -6
  35. package/dist/routes/feed/sitemap.js +11 -8
  36. package/dist/routes/pages/archive.js +13 -15
  37. package/dist/routes/pages/collection.js +12 -9
  38. package/dist/routes/pages/collections.js +28 -0
  39. package/dist/routes/pages/featured.js +32 -0
  40. package/dist/routes/pages/home.js +19 -68
  41. package/dist/routes/pages/page.js +57 -29
  42. package/dist/routes/pages/post.js +7 -17
  43. package/dist/routes/pages/search.js +5 -9
  44. package/dist/services/collection.js +52 -64
  45. package/dist/services/index.js +5 -3
  46. package/dist/services/navigation.js +29 -53
  47. package/dist/services/page.js +84 -0
  48. package/dist/services/post.js +102 -69
  49. package/dist/services/search.js +24 -18
  50. package/dist/types.js +24 -40
  51. package/dist/ui/compose/ComposeDialog.js +452 -0
  52. package/dist/ui/compose/ComposePrompt.js +55 -0
  53. package/dist/{theme/components/TypeBadge.js → ui/dash/FormatBadge.js} +3 -15
  54. package/dist/{theme/components → ui/dash}/PageForm.js +15 -15
  55. package/dist/{theme/components → ui/dash}/PostForm.js +117 -137
  56. package/dist/{theme/components → ui/dash}/PostList.js +18 -13
  57. package/dist/ui/dash/StatusBadge.js +46 -0
  58. package/dist/{theme/components → ui/dash}/index.js +3 -6
  59. package/dist/ui/feed/LinkCard.js +72 -0
  60. package/dist/ui/feed/NoteCard.js +58 -0
  61. package/dist/{themes/minimal/timeline → ui/feed}/QuoteCard.js +29 -14
  62. package/dist/{themes/minimal/timeline → ui/feed}/ThreadPreview.js +20 -18
  63. package/dist/ui/feed/TimelineFeed.js +41 -0
  64. package/dist/ui/feed/TimelineItem.js +27 -0
  65. package/dist/{theme → ui}/layouts/BaseLayout.js +10 -0
  66. package/dist/{theme → ui}/layouts/DashLayout.js +0 -8
  67. package/dist/ui/layouts/SiteLayout.js +141 -0
  68. package/dist/{themes/minimal → ui}/pages/ArchivePage.js +37 -50
  69. package/dist/ui/pages/CollectionPage.js +70 -0
  70. package/dist/ui/pages/CollectionsPage.js +76 -0
  71. package/dist/ui/pages/FeaturedPage.js +24 -0
  72. package/dist/ui/pages/HomePage.js +24 -0
  73. package/dist/{themes/minimal → ui}/pages/PostPage.js +20 -12
  74. package/dist/{themes/minimal → ui}/pages/SearchPage.js +19 -18
  75. package/dist/{themes/minimal → ui}/pages/SinglePage.js +5 -4
  76. package/dist/ui/shared/MediaGallery.js +35 -0
  77. package/dist/{theme/components → ui/shared}/Pagination.js +41 -2
  78. package/dist/{theme/components → ui/shared}/ThreadView.js +3 -3
  79. package/dist/ui/shared/index.js +5 -0
  80. package/package.json +2 -9
  81. package/src/__tests__/helpers/app.ts +4 -0
  82. package/src/__tests__/helpers/db.ts +53 -73
  83. package/src/app.tsx +56 -28
  84. package/src/db/migrations/0005_v2_schema_migration.sql +268 -0
  85. package/src/db/migrations/0006_rename_slug_to_path.sql +5 -0
  86. package/src/db/migrations/meta/_journal.json +14 -0
  87. package/src/db/schema.ts +63 -46
  88. package/src/i18n/locales/en.po +443 -240
  89. package/src/i18n/locales/en.ts +1 -1
  90. package/src/i18n/locales/zh-Hans.po +443 -240
  91. package/src/i18n/locales/zh-Hans.ts +1 -1
  92. package/src/i18n/locales/zh-Hant.po +443 -240
  93. package/src/i18n/locales/zh-Hant.ts +1 -1
  94. package/src/index.ts +29 -42
  95. package/src/lib/__tests__/excerpt.test.ts +125 -0
  96. package/src/lib/__tests__/schemas.test.ts +201 -99
  97. package/src/lib/__tests__/time.test.ts +62 -0
  98. package/src/{routes/api → lib}/__tests__/timeline.test.ts +81 -75
  99. package/src/lib/__tests__/view.test.ts +204 -50
  100. package/src/lib/constants.ts +2 -4
  101. package/src/lib/excerpt.ts +87 -0
  102. package/src/lib/feed.ts +22 -7
  103. package/src/lib/nav-reorder.ts +1 -1
  104. package/src/lib/navigation.ts +45 -8
  105. package/src/lib/pagination.ts +50 -0
  106. package/src/lib/render.tsx +7 -14
  107. package/src/lib/schemas.ts +119 -51
  108. package/src/lib/theme.ts +5 -5
  109. package/src/lib/time.ts +64 -0
  110. package/src/lib/timeline.ts +141 -0
  111. package/src/lib/view.ts +80 -82
  112. package/src/preset.css +46 -0
  113. package/src/routes/__tests__/compose.test.ts +199 -0
  114. package/src/routes/api/__tests__/collections.test.ts +249 -0
  115. package/src/routes/api/__tests__/nav-items.test.ts +222 -0
  116. package/src/routes/api/__tests__/pages.test.ts +218 -0
  117. package/src/routes/api/__tests__/posts.test.ts +50 -108
  118. package/src/routes/api/__tests__/search.test.ts +2 -3
  119. package/src/routes/api/__tests__/settings.test.ts +132 -0
  120. package/src/routes/api/collections.ts +143 -0
  121. package/src/routes/api/nav-items.ts +115 -0
  122. package/src/routes/api/pages.ts +101 -0
  123. package/src/routes/api/posts.ts +28 -28
  124. package/src/routes/api/search.ts +3 -3
  125. package/src/routes/api/settings.ts +91 -0
  126. package/src/routes/api/upload.ts +16 -6
  127. package/src/routes/compose.ts +63 -0
  128. package/src/routes/dash/__tests__/pages.test.ts +225 -0
  129. package/src/routes/dash/collections.tsx +20 -42
  130. package/src/routes/dash/index.tsx +3 -3
  131. package/src/routes/dash/media.tsx +2 -2
  132. package/src/routes/dash/pages.tsx +480 -122
  133. package/src/routes/dash/posts.tsx +42 -54
  134. package/src/routes/dash/redirects.tsx +2 -2
  135. package/src/routes/dash/settings.tsx +83 -5
  136. package/src/routes/feed/rss.ts +4 -3
  137. package/src/routes/feed/sitemap.ts +15 -5
  138. package/src/routes/pages/__tests__/collections.test.ts +94 -0
  139. package/src/routes/pages/__tests__/featured.test.ts +94 -0
  140. package/src/routes/pages/archive.tsx +15 -15
  141. package/src/routes/pages/collection.tsx +16 -9
  142. package/src/routes/pages/collections.tsx +36 -0
  143. package/src/routes/pages/featured.tsx +38 -0
  144. package/src/routes/pages/home.tsx +21 -92
  145. package/src/routes/pages/page.tsx +62 -27
  146. package/src/routes/pages/post.tsx +6 -18
  147. package/src/routes/pages/search.tsx +3 -7
  148. package/src/services/__tests__/collection.test.ts +257 -158
  149. package/src/services/__tests__/media.test.ts +18 -18
  150. package/src/services/__tests__/navigation.test.ts +161 -87
  151. package/src/services/__tests__/page.test.ts +106 -0
  152. package/src/services/__tests__/post-timeline.test.ts +92 -88
  153. package/src/services/__tests__/post.test.ts +432 -197
  154. package/src/services/__tests__/search.test.ts +19 -25
  155. package/src/services/collection.ts +71 -113
  156. package/src/services/index.ts +9 -8
  157. package/src/services/navigation.ts +38 -71
  158. package/src/services/page.ts +136 -0
  159. package/src/services/post.ts +141 -101
  160. package/src/services/search.ts +38 -27
  161. package/src/styles/tokens.css +47 -0
  162. package/src/styles/ui.css +491 -0
  163. package/src/types.ts +212 -198
  164. package/src/ui/compose/ComposeDialog.tsx +395 -0
  165. package/src/ui/compose/ComposePrompt.tsx +55 -0
  166. package/src/ui/dash/FormatBadge.tsx +28 -0
  167. package/src/{theme/components → ui/dash}/PageForm.tsx +21 -21
  168. package/src/{theme/components → ui/dash}/PostForm.tsx +110 -131
  169. package/src/ui/dash/PostList.tsx +101 -0
  170. package/src/ui/dash/StatusBadge.tsx +61 -0
  171. package/src/ui/dash/index.ts +10 -0
  172. package/src/ui/feed/LinkCard.tsx +72 -0
  173. package/src/ui/feed/NoteCard.tsx +63 -0
  174. package/src/ui/feed/QuoteCard.tsx +68 -0
  175. package/src/ui/feed/ThreadPreview.tsx +48 -0
  176. package/src/ui/feed/TimelineFeed.tsx +49 -0
  177. package/src/ui/feed/TimelineItem.tsx +45 -0
  178. package/src/{theme → ui}/layouts/BaseLayout.tsx +11 -1
  179. package/src/{theme → ui}/layouts/DashLayout.tsx +0 -10
  180. package/src/ui/layouts/SiteLayout.tsx +150 -0
  181. package/src/ui/pages/ArchivePage.tsx +162 -0
  182. package/src/ui/pages/CollectionPage.tsx +70 -0
  183. package/src/ui/pages/CollectionsPage.tsx +73 -0
  184. package/src/ui/pages/FeaturedPage.tsx +31 -0
  185. package/src/ui/pages/HomePage.tsx +37 -0
  186. package/src/ui/pages/PostPage.tsx +56 -0
  187. package/src/{themes/minimal → ui}/pages/SearchPage.tsx +24 -20
  188. package/src/{themes/minimal → ui}/pages/SinglePage.tsx +5 -5
  189. package/src/ui/shared/MediaGallery.tsx +59 -0
  190. package/src/{theme/components → ui/shared}/Pagination.tsx +67 -4
  191. package/src/{theme/components → ui/shared}/ThreadView.tsx +6 -3
  192. package/src/ui/shared/__tests__/pagination.test.ts +46 -0
  193. package/src/ui/shared/index.ts +12 -0
  194. package/bin/jant.js +0 -185
  195. package/dist/lib/theme-components.js +0 -49
  196. package/dist/routes/api/timeline.js +0 -120
  197. package/dist/routes/dash/navigation.js +0 -288
  198. package/dist/theme/components/MediaGallery.js +0 -107
  199. package/dist/theme/components/VisibilityBadge.js +0 -37
  200. package/dist/theme/index.js +0 -18
  201. package/dist/theme/layouts/index.js +0 -2
  202. package/dist/themes/minimal/MinimalSiteLayout.js +0 -83
  203. package/dist/themes/minimal/index.js +0 -65
  204. package/dist/themes/minimal/pages/CollectionPage.js +0 -65
  205. package/dist/themes/minimal/pages/HomePage.js +0 -25
  206. package/dist/themes/minimal/timeline/ArticleCard.js +0 -36
  207. package/dist/themes/minimal/timeline/ImageCard.js +0 -67
  208. package/dist/themes/minimal/timeline/LinkCard.js +0 -47
  209. package/dist/themes/minimal/timeline/NoteCard.js +0 -34
  210. package/dist/themes/minimal/timeline/TimelineFeed.js +0 -48
  211. package/dist/themes/minimal/timeline/TimelineItem.js +0 -44
  212. package/src/lib/__tests__/theme-components.test.ts +0 -126
  213. package/src/lib/theme-components.ts +0 -68
  214. package/src/routes/api/timeline.tsx +0 -159
  215. package/src/routes/dash/navigation.tsx +0 -316
  216. package/src/theme/components/MediaGallery.tsx +0 -128
  217. package/src/theme/components/PostList.tsx +0 -92
  218. package/src/theme/components/TypeBadge.tsx +0 -37
  219. package/src/theme/components/VisibilityBadge.tsx +0 -45
  220. package/src/theme/components/index.ts +0 -23
  221. package/src/theme/index.ts +0 -22
  222. package/src/theme/layouts/index.ts +0 -7
  223. package/src/themes/minimal/MinimalSiteLayout.tsx +0 -100
  224. package/src/themes/minimal/index.ts +0 -83
  225. package/src/themes/minimal/pages/ArchivePage.tsx +0 -157
  226. package/src/themes/minimal/pages/CollectionPage.tsx +0 -60
  227. package/src/themes/minimal/pages/HomePage.tsx +0 -41
  228. package/src/themes/minimal/pages/PostPage.tsx +0 -43
  229. package/src/themes/minimal/timeline/ArticleCard.tsx +0 -37
  230. package/src/themes/minimal/timeline/ImageCard.tsx +0 -63
  231. package/src/themes/minimal/timeline/LinkCard.tsx +0 -48
  232. package/src/themes/minimal/timeline/NoteCard.tsx +0 -35
  233. package/src/themes/minimal/timeline/QuoteCard.tsx +0 -49
  234. package/src/themes/minimal/timeline/ThreadPreview.tsx +0 -47
  235. package/src/themes/minimal/timeline/TimelineFeed.tsx +0 -57
  236. package/src/themes/minimal/timeline/TimelineItem.tsx +0 -75
  237. /package/dist/{theme → ui}/color-themes.js +0 -0
  238. /package/dist/{theme/components → ui/dash}/ActionButtons.js +0 -0
  239. /package/dist/{theme/components → ui/dash}/CrudPageHeader.js +0 -0
  240. /package/dist/{theme/components → ui/dash}/DangerZone.js +0 -0
  241. /package/dist/{theme/components → ui/dash}/ListItemRow.js +0 -0
  242. /package/dist/{theme/components → ui/shared}/EmptyState.js +0 -0
  243. /package/src/{theme → ui}/color-themes.ts +0 -0
  244. /package/src/{theme/components → ui/dash}/ActionButtons.tsx +0 -0
  245. /package/src/{theme/components → ui/dash}/CrudPageHeader.tsx +0 -0
  246. /package/src/{theme/components → ui/dash}/DangerZone.tsx +0 -0
  247. /package/src/{theme/components → ui/dash}/ListItemRow.tsx +0 -0
  248. /package/src/{theme/components → ui/shared}/EmptyState.tsx +0 -0
@@ -0,0 +1,491 @@
1
+ /**
2
+ * UI Component Styles
3
+ *
4
+ * All styles reference design tokens from tokens.css.
5
+ * Class names are the stable public API — DO NOT rename without a major version bump.
6
+ */
7
+
8
+ /* Tell Tailwind to scan ui/ source files for class usage */
9
+ @source "../ui/";
10
+
11
+ @layer components {
12
+ /* =========================================================================
13
+ * Page Layout
14
+ * ========================================================================= */
15
+
16
+ .site-page {
17
+ min-height: 100vh;
18
+ min-height: 100dvh;
19
+ background-color: var(--site-page-bg);
20
+ }
21
+
22
+ /* --- Top header --------------------------------------------------------- */
23
+
24
+ .site-header {
25
+ max-width: var(--site-width);
26
+ margin: 0 auto;
27
+ padding: 20px var(--site-padding) 0;
28
+ }
29
+
30
+ @media (min-width: 700px) {
31
+ .site-header {
32
+ padding: 24px var(--site-padding) 0;
33
+ }
34
+ }
35
+
36
+ .site-header-inner {
37
+ display: flex;
38
+ flex-direction: column;
39
+ align-items: flex-start;
40
+ gap: 10px;
41
+ }
42
+
43
+ .site-header-top {
44
+ display: flex;
45
+ align-items: center;
46
+ justify-content: space-between;
47
+ width: 100%;
48
+ }
49
+
50
+ .site-header-top-bordered {
51
+ padding-bottom: 12px;
52
+ border-bottom: 0.5px solid var(--site-divider);
53
+ }
54
+
55
+ .site-header-right {
56
+ display: flex;
57
+ align-items: center;
58
+ gap: 12px;
59
+ }
60
+
61
+ .site-header-search {
62
+ display: flex;
63
+ align-items: center;
64
+ justify-content: center;
65
+ width: 32px;
66
+ height: 32px;
67
+ border-radius: 999px;
68
+ color: var(--site-text-secondary);
69
+ transition:
70
+ color 0.15s,
71
+ background-color 0.15s;
72
+ }
73
+
74
+ .site-header-search:hover {
75
+ color: var(--site-text-primary);
76
+ background-color: var(--site-nav-hover-bg);
77
+ }
78
+
79
+ .site-header-search-active {
80
+ color: var(--site-text-primary);
81
+ background-color: var(--site-nav-hover-bg);
82
+ }
83
+
84
+ .site-logo {
85
+ font-size: 1.125rem;
86
+ font-weight: 800;
87
+ font-family: var(--font-heading);
88
+ color: var(--site-text-primary);
89
+ text-decoration: none;
90
+ line-height: 1;
91
+ }
92
+
93
+ .site-header-nav {
94
+ display: flex;
95
+ align-items: center;
96
+ gap: 12px;
97
+ }
98
+
99
+ .site-header-link {
100
+ font-size: 0.875rem;
101
+ color: var(--site-text-secondary);
102
+ text-decoration: underline transparent;
103
+ text-underline-offset: 3px;
104
+ text-decoration-thickness: 0.5px;
105
+ transition:
106
+ color 0.15s,
107
+ text-decoration-color 0.15s;
108
+ }
109
+
110
+ .site-header-link:hover {
111
+ color: var(--site-text-primary);
112
+ text-decoration-color: var(--site-text-secondary);
113
+ }
114
+
115
+ .site-header-link-active {
116
+ color: var(--site-text-primary);
117
+ }
118
+
119
+ .site-description {
120
+ font-size: var(--text-sm);
121
+ color: var(--site-text-secondary);
122
+ margin: 2px 0 0;
123
+ line-height: var(--leading);
124
+ }
125
+
126
+ /* --- Browse filter tabs ------------------------------------------------- */
127
+
128
+ .site-browse-nav {
129
+ display: flex;
130
+ align-items: center;
131
+ gap: 8px;
132
+ padding: 16px 0 var(--space-xl);
133
+ }
134
+
135
+ .site-browse-sep {
136
+ color: var(--site-divider);
137
+ font-size: var(--text-sm);
138
+ }
139
+
140
+ .site-browse-link {
141
+ font-size: var(--text-base);
142
+ color: var(--site-text-secondary);
143
+ text-decoration: none;
144
+ font-weight: 500;
145
+ transition: color 0.15s;
146
+ }
147
+
148
+ .site-browse-link:hover {
149
+ color: var(--site-text-primary);
150
+ }
151
+
152
+ .site-browse-link-active {
153
+ color: var(--site-text-primary);
154
+ font-weight: 700;
155
+ }
156
+
157
+ /* --- Main content area -------------------------------------------------- */
158
+
159
+ .site-container {
160
+ max-width: var(--site-width);
161
+ margin: 0 auto;
162
+ }
163
+
164
+ .site-content {
165
+ background-color: var(--site-elevated-bg);
166
+ padding: 0 var(--site-padding);
167
+ }
168
+
169
+ /* =========================================================================
170
+ * Timeline & Post Components
171
+ * ========================================================================= */
172
+
173
+ /* Post divider */
174
+ .site-content hr.feed-divider {
175
+ border: none;
176
+ height: 10px;
177
+ width: 32px;
178
+ margin: 3rem auto;
179
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 45 13'%3E%3Cpath fill='%23ccc' transform='translate(0,0) rotate(90 6 6.5)' d='M6.765.5.177 6.093l2.61 5.966 8.39-3.17L6.765.5Z'/%3E%3Cpath fill='%23ccc' transform='translate(16,0) rotate(100 6 6.5)' d='M6.765.5.177 6.093l2.61 5.966 8.39-3.17L6.765.5Z'/%3E%3Cpath fill='%23ccc' transform='translate(32,0) rotate(80 6 6.5)' d='M6.765.5.177 6.093l2.61 5.966 8.39-3.17L6.765.5Z'/%3E%3C/svg%3E");
180
+ background-repeat: no-repeat;
181
+ background-position: center;
182
+ }
183
+
184
+ /* Thread reply container with vertical connector line */
185
+ .feed-replies {
186
+ position: relative;
187
+ margin-left: 16px;
188
+ padding-left: 16px;
189
+ margin-top: 8px;
190
+ }
191
+
192
+ .feed-replies::before {
193
+ content: "";
194
+ position: absolute;
195
+ left: 0;
196
+ top: 0;
197
+ bottom: 0;
198
+ width: 2px;
199
+ background-color: var(--site-threadline);
200
+ }
201
+
202
+ /* Individual reply in thread */
203
+ .feed-reply {
204
+ padding: 12px 0;
205
+ }
206
+
207
+ .feed-reply + .feed-reply {
208
+ border-top: var(--card-border-width) solid var(--site-divider);
209
+ }
210
+
211
+ /* Compact text for thread replies */
212
+ .feed-compact {
213
+ @apply text-sm;
214
+ }
215
+
216
+ /* Media — rounded corners + subtle outline */
217
+ .feed-media img {
218
+ border-radius: var(--media-radius);
219
+ outline: 1px solid var(--site-media-outline);
220
+ outline-offset: -1px;
221
+ }
222
+
223
+ /* Image carousel — horizontal scroll */
224
+ .feed-carousel-track {
225
+ display: flex;
226
+ overflow-x: auto;
227
+ gap: 4px;
228
+ margin-inline: calc(-1 * var(--site-padding));
229
+ padding-inline: var(--site-padding);
230
+ scrollbar-width: none; /* Firefox */
231
+ -ms-overflow-style: none; /* IE/Edge */
232
+ }
233
+ .feed-carousel-track::-webkit-scrollbar {
234
+ display: none; /* Chrome/Safari */
235
+ }
236
+ .feed-carousel-item {
237
+ flex: 0 0 auto;
238
+ width: 224px;
239
+ height: 280px;
240
+ }
241
+ .feed-carousel-img {
242
+ width: 100%;
243
+ height: 100%;
244
+ object-fit: cover;
245
+ }
246
+
247
+ /* Link preview styling */
248
+ .feed-link-preview {
249
+ border-radius: 12px;
250
+ border: var(--card-border-width) solid var(--site-column-outline);
251
+ padding: 12px 16px;
252
+ margin-top: 8px;
253
+ }
254
+
255
+ /* Quote block styling */
256
+ .feed-quote {
257
+ padding-left: 12px;
258
+ border-left: 2px solid var(--site-text-secondary);
259
+ }
260
+
261
+ /* =========================================================================
262
+ * Compose Prompt Bar ("What's new?" at top of content)
263
+ * ========================================================================= */
264
+
265
+ .compose-prompt {
266
+ display: flex;
267
+ align-items: center;
268
+ gap: 12px;
269
+ padding: 16px 0;
270
+ margin: -20px 0 12px;
271
+ }
272
+
273
+ .compose-prompt-trigger {
274
+ display: flex;
275
+ align-items: center;
276
+ gap: 10px;
277
+ flex: 1;
278
+ min-width: 0;
279
+ padding: 0;
280
+ border: none;
281
+ background: none;
282
+ cursor: pointer;
283
+ text-align: left;
284
+ }
285
+
286
+ .compose-prompt-avatar {
287
+ display: flex;
288
+ align-items: center;
289
+ justify-content: center;
290
+ width: var(--avatar-size);
291
+ height: var(--avatar-size);
292
+ flex-shrink: 0;
293
+ border-radius: var(--avatar-radius);
294
+ border: 1.5px solid var(--site-column-outline);
295
+ color: var(--site-text-secondary);
296
+ }
297
+
298
+ .compose-prompt-text {
299
+ font-size: var(--text-base);
300
+ color: var(--site-text-secondary);
301
+ }
302
+
303
+ .compose-prompt-post-btn {
304
+ flex-shrink: 0;
305
+ padding: 6px 16px;
306
+ border-radius: 10px;
307
+ border: 1px solid var(--site-column-outline);
308
+ background: none;
309
+ color: var(--site-text-secondary);
310
+ font-size: 0.875rem;
311
+ font-weight: 600;
312
+ cursor: pointer;
313
+ transition:
314
+ border-color 0.15s,
315
+ color 0.15s;
316
+ }
317
+
318
+ .compose-prompt-post-btn:hover {
319
+ color: var(--site-text-primary);
320
+ border-color: var(--site-text-secondary);
321
+ }
322
+
323
+ /* =========================================================================
324
+ * Compose Dialog
325
+ * ========================================================================= */
326
+
327
+ /* Dialog — positioned near top of viewport */
328
+ .compose-dialog {
329
+ padding: 0;
330
+ border: none;
331
+ border-radius: 16px;
332
+ max-width: 560px;
333
+ width: calc(100% - 32px);
334
+ max-height: calc(100dvh - 64px);
335
+ margin: max(80px, 10vh) auto auto;
336
+ background-color: var(--site-elevated-bg);
337
+ color: var(--site-text-primary);
338
+ box-shadow:
339
+ 0 25px 50px -12px rgba(0, 0, 0, 0.25),
340
+ 0 0 0 1px var(--site-column-outline);
341
+ }
342
+
343
+ .compose-dialog::backdrop {
344
+ background-color: rgba(0, 0, 0, 0.5);
345
+ }
346
+
347
+ .compose-dialog-inner {
348
+ display: flex;
349
+ flex-direction: column;
350
+ max-height: calc(100dvh - 64px);
351
+ }
352
+
353
+ .compose-dialog-header {
354
+ display: flex;
355
+ align-items: center;
356
+ justify-content: space-between;
357
+ padding: 16px 20px;
358
+ border-bottom: var(--card-border-width) solid var(--site-divider);
359
+ }
360
+
361
+ .compose-dialog-title {
362
+ font-size: 1rem;
363
+ font-weight: 600;
364
+ margin: 0;
365
+ }
366
+
367
+ .compose-dialog-close {
368
+ display: flex;
369
+ align-items: center;
370
+ justify-content: center;
371
+ width: 28px;
372
+ height: 28px;
373
+ border-radius: 50%;
374
+ border: none;
375
+ background: none;
376
+ color: var(--site-text-secondary);
377
+ cursor: pointer;
378
+ transition: background-color 0.15s;
379
+ }
380
+
381
+ .compose-dialog-close:hover {
382
+ background-color: var(--site-nav-hover-bg);
383
+ }
384
+
385
+ .compose-dialog-body {
386
+ padding: 16px 20px;
387
+ overflow-y: auto;
388
+ flex: 1;
389
+ }
390
+
391
+ .compose-dialog-footer {
392
+ display: flex;
393
+ align-items: center;
394
+ justify-content: space-between;
395
+ padding-top: 12px;
396
+ border-top: var(--card-border-width) solid var(--site-divider);
397
+ }
398
+
399
+ /* Format tabs — inline pill buttons */
400
+ .compose-format-tabs {
401
+ display: flex;
402
+ gap: 4px;
403
+ padding-bottom: 8px;
404
+ }
405
+
406
+ .compose-format-tab {
407
+ padding: 4px 12px;
408
+ border-radius: 999px;
409
+ border: 1px solid var(--site-column-outline);
410
+ background: none;
411
+ color: var(--site-text-secondary);
412
+ font-size: var(--text-sm);
413
+ cursor: pointer;
414
+ transition:
415
+ background-color 0.15s,
416
+ color 0.15s,
417
+ border-color 0.15s;
418
+ }
419
+
420
+ .compose-format-tab:hover {
421
+ color: var(--site-text-primary);
422
+ border-color: var(--site-text-secondary);
423
+ }
424
+
425
+ .compose-format-tab-active {
426
+ color: var(--site-text-primary);
427
+ background-color: var(--site-nav-hover-bg);
428
+ border-color: var(--site-text-primary);
429
+ font-weight: 500;
430
+ }
431
+
432
+ /* Borderless title input */
433
+ .compose-title-input {
434
+ width: 100%;
435
+ padding: 4px 0;
436
+ border: none;
437
+ outline: none;
438
+ background: transparent;
439
+ color: var(--site-text-primary);
440
+ font-size: var(--text-lg);
441
+ font-weight: 600;
442
+ }
443
+
444
+ .compose-title-input::placeholder {
445
+ color: var(--site-text-secondary);
446
+ font-weight: 400;
447
+ }
448
+
449
+ /* Borderless body textarea */
450
+ .compose-body-input {
451
+ width: 100%;
452
+ padding: 4px 0;
453
+ border: none;
454
+ outline: none;
455
+ background: transparent;
456
+ color: var(--site-text-primary);
457
+ font-size: var(--text-base);
458
+ line-height: var(--leading);
459
+ resize: vertical;
460
+ }
461
+
462
+ .compose-body-input::placeholder {
463
+ color: var(--site-text-secondary);
464
+ }
465
+
466
+ /* Bottom toolbar */
467
+ .compose-toolbar {
468
+ padding: 8px 0;
469
+ }
470
+
471
+ .compose-toolbar-btn {
472
+ display: flex;
473
+ align-items: center;
474
+ justify-content: center;
475
+ width: 32px;
476
+ height: 32px;
477
+ border-radius: 8px;
478
+ border: none;
479
+ background: none;
480
+ color: var(--site-text-secondary);
481
+ cursor: pointer;
482
+ transition:
483
+ background-color 0.15s,
484
+ color 0.15s;
485
+ }
486
+
487
+ .compose-toolbar-btn:hover {
488
+ color: var(--site-text-primary);
489
+ background-color: var(--site-nav-hover-bg);
490
+ }
491
+ }