@okjavis/nodebb-theme-javis 2.5.3 → 3.0.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.
- package/package.json +1 -1
- package/scss/_cards.scss +69 -22
- package/scss/_categories.scss +424 -39
- package/scss/_topic.scss +1 -1
- package/templates/category.tpl +95 -0
- package/templates/partials/categories/item.tpl +67 -0
- package/templates/partials/categories/lastpost.tpl +30 -0
- package/templates/partials/categories/link.tpl +5 -0
- package/templates/partials/topics_list.tpl +20 -11
package/package.json
CHANGED
package/scss/_cards.scss
CHANGED
|
@@ -43,10 +43,10 @@
|
|
|
43
43
|
flex-direction: column;
|
|
44
44
|
align-items: center;
|
|
45
45
|
justify-content: flex-start;
|
|
46
|
-
padding: $jv-space-
|
|
46
|
+
padding: $jv-space-4 $jv-space-3; // Tighter padding
|
|
47
47
|
background: rgba(0, 0, 0, 0.02);
|
|
48
|
-
min-width:
|
|
49
|
-
gap:
|
|
48
|
+
min-width: 40px;
|
|
49
|
+
gap: 2px; // Minimal gap
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
.vote-btn {
|
|
@@ -100,10 +100,10 @@
|
|
|
100
100
|
// ===========================================================
|
|
101
101
|
.topic-content {
|
|
102
102
|
flex: 1;
|
|
103
|
-
padding: $jv-space-3;
|
|
103
|
+
padding: $jv-space-3;
|
|
104
104
|
display: flex;
|
|
105
105
|
flex-direction: column;
|
|
106
|
-
gap: $jv-space-
|
|
106
|
+
gap: $jv-space-2; // Tighter gap between elements
|
|
107
107
|
min-width: 0; // Allow text truncation
|
|
108
108
|
}
|
|
109
109
|
|
|
@@ -147,10 +147,10 @@
|
|
|
147
147
|
// Topic Title
|
|
148
148
|
.topic-card .topic-title {
|
|
149
149
|
margin: 0;
|
|
150
|
-
font-size:
|
|
151
|
-
font-weight:
|
|
152
|
-
line-height:
|
|
153
|
-
letter-spacing: -0.02em;
|
|
150
|
+
font-size: $jv-font-size-lg; // 18px - clear hierarchy
|
|
151
|
+
font-weight: 600; // Semi-bold
|
|
152
|
+
line-height: $jv-line-height-tight;
|
|
153
|
+
letter-spacing: -0.02em;
|
|
154
154
|
|
|
155
155
|
a {
|
|
156
156
|
color: $jv-text-main;
|
|
@@ -260,7 +260,7 @@
|
|
|
260
260
|
color: $jv-text-muted;
|
|
261
261
|
line-height: $jv-line-height-base;
|
|
262
262
|
display: -webkit-box;
|
|
263
|
-
-webkit-line-clamp: 3
|
|
263
|
+
-webkit-line-clamp: 2; // Reduced from 3 to 2 lines
|
|
264
264
|
-webkit-box-orient: vertical;
|
|
265
265
|
overflow: hidden;
|
|
266
266
|
|
|
@@ -270,6 +270,54 @@
|
|
|
270
270
|
}
|
|
271
271
|
}
|
|
272
272
|
|
|
273
|
+
// ===========================================================
|
|
274
|
+
// MEDIA ROW (Image + Text side by side)
|
|
275
|
+
// ===========================================================
|
|
276
|
+
.topic-media-row {
|
|
277
|
+
display: flex;
|
|
278
|
+
gap: $jv-space-4;
|
|
279
|
+
align-items: flex-start;
|
|
280
|
+
|
|
281
|
+
.topic-media-text {
|
|
282
|
+
flex: 1;
|
|
283
|
+
min-width: 0; // Allow text truncation
|
|
284
|
+
|
|
285
|
+
.topic-teaser {
|
|
286
|
+
-webkit-line-clamp: 3; // Allow more lines when beside image
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
.topic-thumbnail {
|
|
291
|
+
flex-shrink: 0;
|
|
292
|
+
width: 140px;
|
|
293
|
+
height: 100px;
|
|
294
|
+
|
|
295
|
+
img {
|
|
296
|
+
width: 100%;
|
|
297
|
+
height: 100%;
|
|
298
|
+
object-fit: cover;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
@media (max-width: 576px) {
|
|
304
|
+
.topic-media-row {
|
|
305
|
+
flex-direction: column-reverse;
|
|
306
|
+
gap: $jv-space-3;
|
|
307
|
+
|
|
308
|
+
.topic-thumbnail {
|
|
309
|
+
width: 100%;
|
|
310
|
+
height: auto;
|
|
311
|
+
max-height: 180px;
|
|
312
|
+
|
|
313
|
+
img {
|
|
314
|
+
max-height: 180px;
|
|
315
|
+
width: 100%;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
273
321
|
// ===========================================================
|
|
274
322
|
// ACTION BAR (Bottom - Reddit style)
|
|
275
323
|
// ===========================================================
|
|
@@ -298,21 +346,21 @@ li[component="post"] hr,
|
|
|
298
346
|
.action-btn {
|
|
299
347
|
display: inline-flex;
|
|
300
348
|
align-items: center;
|
|
301
|
-
gap: $jv-space-
|
|
302
|
-
padding: $jv-space-
|
|
303
|
-
font-size:
|
|
304
|
-
font-weight:
|
|
305
|
-
color: $jv-text-
|
|
349
|
+
gap: $jv-space-1; // Tighter gap
|
|
350
|
+
padding: $jv-space-1 $jv-space-2; // Smaller padding
|
|
351
|
+
font-size: $jv-font-size-xs; // Smaller font
|
|
352
|
+
font-weight: 500; // Lighter weight
|
|
353
|
+
color: $jv-text-soft; // More subtle color
|
|
306
354
|
background: transparent;
|
|
307
355
|
border: none;
|
|
308
|
-
border-radius: $jv-radius-
|
|
356
|
+
border-radius: $jv-radius-xs;
|
|
309
357
|
cursor: pointer;
|
|
310
358
|
text-decoration: none;
|
|
311
|
-
transition: background-color $jv-transition-fast, color $jv-transition-fast;
|
|
359
|
+
transition: background-color $jv-transition-fast, color $jv-transition-fast;
|
|
312
360
|
|
|
313
361
|
&:hover {
|
|
314
|
-
background: $jv-hover-bg;
|
|
315
|
-
color: $jv-text-
|
|
362
|
+
background: $jv-hover-bg;
|
|
363
|
+
color: $jv-text-muted;
|
|
316
364
|
}
|
|
317
365
|
|
|
318
366
|
// Focus state for accessibility
|
|
@@ -322,12 +370,11 @@ li[component="post"] hr,
|
|
|
322
370
|
}
|
|
323
371
|
|
|
324
372
|
i {
|
|
325
|
-
font-size:
|
|
373
|
+
font-size: 14px; // Smaller icons
|
|
326
374
|
}
|
|
327
375
|
|
|
328
|
-
// Make numbers bold
|
|
329
376
|
span {
|
|
330
|
-
font-weight:
|
|
377
|
+
font-weight: 500; // Normal weight, not bold
|
|
331
378
|
}
|
|
332
379
|
}
|
|
333
380
|
|
package/scss/_categories.scss
CHANGED
|
@@ -1,58 +1,93 @@
|
|
|
1
1
|
// ===========================================================
|
|
2
|
-
// CATEGORIES –
|
|
2
|
+
// CATEGORIES – Reddit/Community Style Cards
|
|
3
|
+
// Matches topic-card design for visual consistency
|
|
3
4
|
// ===========================================================
|
|
4
5
|
|
|
5
6
|
// Category Header
|
|
6
7
|
.feed h2 {
|
|
7
|
-
font-size:
|
|
8
|
+
font-size: $jv-font-size-base;
|
|
8
9
|
font-weight: 600;
|
|
9
|
-
margin: 0 0 $jv-space-6 0;
|
|
10
|
+
margin: 0 0 $jv-space-6 0;
|
|
10
11
|
padding: 0;
|
|
11
12
|
color: $jv-text-main;
|
|
12
13
|
letter-spacing: -0.2px;
|
|
13
14
|
}
|
|
14
15
|
|
|
15
|
-
// Wrapper list spacing
|
|
16
|
+
// Wrapper list spacing - cards with gaps
|
|
16
17
|
ul.categories-list.list-unstyled {
|
|
17
18
|
margin: 0;
|
|
18
19
|
padding: 0;
|
|
19
20
|
display: flex;
|
|
20
21
|
flex-direction: column;
|
|
21
|
-
gap:
|
|
22
|
+
gap: $jv-space-3;
|
|
23
|
+
|
|
24
|
+
// First category gets subtle featured treatment
|
|
25
|
+
> li[component="categories/category"]:first-child {
|
|
26
|
+
background: linear-gradient(135deg, rgba($jv-primary, 0.04) 0%, rgba($jv-primary, 0.01) 100%);
|
|
27
|
+
border-color: rgba($jv-primary, 0.2);
|
|
28
|
+
|
|
29
|
+
&:hover {
|
|
30
|
+
border-color: rgba($jv-primary, 0.35);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
22
33
|
}
|
|
23
34
|
|
|
24
35
|
// ===========================================================
|
|
25
|
-
// PARENT CATEGORY
|
|
36
|
+
// PARENT CATEGORY CARD (Consolidated selector)
|
|
26
37
|
// ===========================================================
|
|
27
38
|
|
|
28
39
|
li[component="categories/category"] {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
40
|
+
position: relative;
|
|
41
|
+
background: $jv-surface;
|
|
42
|
+
border-radius: $jv-radius-sm;
|
|
43
|
+
border: 1px solid $jv-border-subtle;
|
|
44
|
+
box-shadow: $jv-shadow-sm;
|
|
45
|
+
padding: $jv-space-5;
|
|
46
|
+
transition: box-shadow $jv-transition-base, border-color $jv-transition-fast, transform $jv-transition-fast;
|
|
36
47
|
|
|
37
48
|
&:hover {
|
|
38
|
-
|
|
49
|
+
box-shadow: $jv-shadow-md;
|
|
50
|
+
border-color: $jv-border-strong;
|
|
51
|
+
transform: translateY(-1px);
|
|
52
|
+
|
|
53
|
+
.subcategory-pill {
|
|
54
|
+
background: $jv-surface;
|
|
55
|
+
}
|
|
39
56
|
}
|
|
40
57
|
|
|
41
|
-
// Focus state for accessibility
|
|
42
58
|
&:focus-within {
|
|
43
59
|
outline: none;
|
|
44
|
-
|
|
60
|
+
box-shadow: $jv-shadow-md, $jv-focus-ring;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Unread state
|
|
64
|
+
&.unread {
|
|
65
|
+
border-left: 3px solid $jv-primary;
|
|
66
|
+
|
|
67
|
+
.title a {
|
|
68
|
+
font-weight: 700;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// New posts indicator
|
|
73
|
+
&.new-posts {
|
|
74
|
+
.activity-badge.active {
|
|
75
|
+
animation: pulse 2s ease-in-out infinite;
|
|
76
|
+
}
|
|
45
77
|
}
|
|
46
78
|
|
|
47
|
-
//
|
|
79
|
+
// ------------------------------------
|
|
80
|
+
// Title
|
|
81
|
+
// ------------------------------------
|
|
48
82
|
.title {
|
|
49
|
-
font-size: $jv-font-size-
|
|
83
|
+
font-size: $jv-font-size-lg;
|
|
50
84
|
font-weight: 600;
|
|
51
85
|
color: $jv-text-main;
|
|
52
|
-
margin-bottom: $jv-space-1; //
|
|
86
|
+
margin-bottom: $jv-space-1; // Tighter spacing to description
|
|
53
87
|
display: flex;
|
|
54
88
|
align-items: center;
|
|
55
|
-
gap: $jv-space-
|
|
89
|
+
gap: $jv-space-3;
|
|
90
|
+
letter-spacing: -0.02em;
|
|
56
91
|
|
|
57
92
|
a {
|
|
58
93
|
text-decoration: none;
|
|
@@ -69,51 +104,173 @@ li[component="categories/category"] {
|
|
|
69
104
|
}
|
|
70
105
|
}
|
|
71
106
|
|
|
72
|
-
//
|
|
107
|
+
// ------------------------------------
|
|
108
|
+
// Description
|
|
109
|
+
// ------------------------------------
|
|
73
110
|
.description {
|
|
74
111
|
font-size: $jv-font-size-sm;
|
|
75
112
|
color: $jv-text-muted;
|
|
76
|
-
line-height:
|
|
77
|
-
margin-bottom: $jv-space-
|
|
78
|
-
max-width:
|
|
113
|
+
line-height: $jv-line-height-base;
|
|
114
|
+
margin-bottom: $jv-space-3;
|
|
115
|
+
max-width: 100%;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// ------------------------------------
|
|
119
|
+
// Category Icon
|
|
120
|
+
// ------------------------------------
|
|
121
|
+
.category-icon,
|
|
122
|
+
[component="category/icon"] {
|
|
123
|
+
width: 48px !important;
|
|
124
|
+
height: 48px !important;
|
|
125
|
+
border-radius: $jv-radius-sm !important;
|
|
126
|
+
display: flex;
|
|
127
|
+
align-items: center;
|
|
128
|
+
justify-content: center;
|
|
129
|
+
font-size: $jv-font-size-lg !important;
|
|
130
|
+
flex-shrink: 0;
|
|
131
|
+
box-shadow: $jv-shadow-xs;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// ------------------------------------
|
|
135
|
+
// Stats - Minimal inline design
|
|
136
|
+
// ------------------------------------
|
|
137
|
+
.stats-minimal {
|
|
138
|
+
.stat-item {
|
|
139
|
+
display: flex;
|
|
140
|
+
flex-direction: column;
|
|
141
|
+
align-items: center;
|
|
142
|
+
gap: 2px;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.stat-number {
|
|
146
|
+
font-size: $jv-font-size-lg;
|
|
147
|
+
font-weight: 600;
|
|
148
|
+
color: $jv-text-main;
|
|
149
|
+
line-height: 1;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.stat-label {
|
|
153
|
+
font-size: $jv-font-size-xs;
|
|
154
|
+
color: $jv-text-soft;
|
|
155
|
+
text-transform: uppercase;
|
|
156
|
+
letter-spacing: 0.3px;
|
|
157
|
+
font-weight: 500;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// ------------------------------------
|
|
162
|
+
// Last Post Teaser
|
|
163
|
+
// ------------------------------------
|
|
164
|
+
.teaser {
|
|
165
|
+
// Reset inherited spacing from NodeBB
|
|
166
|
+
padding-top: 0 !important;
|
|
167
|
+
margin-top: 0 !important;
|
|
168
|
+
border-top: none !important;
|
|
169
|
+
|
|
170
|
+
.teaser-enhanced {
|
|
171
|
+
border-left: 3px solid var(--teaser-color, $jv-primary);
|
|
172
|
+
height: auto !important;
|
|
173
|
+
border-radius: 0 $jv-radius-sm $jv-radius-sm 0;
|
|
174
|
+
background: $jv-bg;
|
|
175
|
+
padding: $jv-space-3;
|
|
176
|
+
transition: background $jv-transition-fast;
|
|
177
|
+
|
|
178
|
+
&:hover {
|
|
179
|
+
background: darken($jv-bg, 2%);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.teaser-header {
|
|
183
|
+
.avatar-tooltip img,
|
|
184
|
+
[component="user/picture"] {
|
|
185
|
+
width: 24px !important;
|
|
186
|
+
height: 24px !important;
|
|
187
|
+
border-radius: $jv-radius-pill;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.teaser-meta {
|
|
191
|
+
display: flex;
|
|
192
|
+
flex-direction: column;
|
|
193
|
+
gap: 0;
|
|
194
|
+
line-height: 1.2;
|
|
195
|
+
|
|
196
|
+
.teaser-user {
|
|
197
|
+
font-size: $jv-font-size-xs;
|
|
198
|
+
font-weight: 600;
|
|
199
|
+
color: $jv-text-main;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
.teaser-time {
|
|
203
|
+
font-size: $jv-font-size-xs;
|
|
204
|
+
color: $jv-text-soft;
|
|
205
|
+
text-decoration: none;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
.teaser-content-wrapper {
|
|
211
|
+
display: flex;
|
|
212
|
+
flex-direction: column;
|
|
213
|
+
gap: $jv-space-1;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
.teaser-content {
|
|
217
|
+
font-size: $jv-font-size-sm;
|
|
218
|
+
color: $jv-text-muted;
|
|
219
|
+
line-height: $jv-line-height-base;
|
|
220
|
+
display: -webkit-box;
|
|
221
|
+
-webkit-line-clamp: 2;
|
|
222
|
+
-webkit-box-orient: vertical;
|
|
223
|
+
overflow: hidden;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
.teaser-read-more {
|
|
227
|
+
font-size: $jv-font-size-xs;
|
|
228
|
+
font-weight: 500;
|
|
229
|
+
color: $jv-primary;
|
|
230
|
+
text-decoration: none;
|
|
231
|
+
transition: color $jv-transition-fast;
|
|
232
|
+
|
|
233
|
+
&:hover {
|
|
234
|
+
color: darken($jv-primary, 10%);
|
|
235
|
+
text-decoration: underline;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
79
239
|
}
|
|
80
240
|
}
|
|
81
241
|
|
|
82
242
|
// ===========================================================
|
|
83
|
-
// CHILD CATEGORY ITEMS –
|
|
243
|
+
// CHILD CATEGORY ITEMS – Subcategory pills
|
|
84
244
|
// ===========================================================
|
|
85
245
|
|
|
86
|
-
|
|
246
|
+
.category-children {
|
|
87
247
|
display: flex;
|
|
88
248
|
flex-direction: column;
|
|
89
|
-
gap: $jv-space-2;
|
|
90
|
-
margin-top: $jv-space-1;
|
|
249
|
+
gap: $jv-space-2;
|
|
250
|
+
margin-top: $jv-space-1;
|
|
91
251
|
}
|
|
92
252
|
|
|
93
253
|
.category-children-item {
|
|
94
254
|
small > .d-flex {
|
|
95
255
|
display: flex;
|
|
96
256
|
align-items: center;
|
|
97
|
-
gap: $jv-space-2;
|
|
98
|
-
font-size:
|
|
99
|
-
color:
|
|
257
|
+
gap: $jv-space-2;
|
|
258
|
+
font-size: $jv-font-size-sm;
|
|
259
|
+
color: $jv-text-main;
|
|
100
260
|
}
|
|
101
261
|
|
|
102
|
-
// Dot (neutral by default)
|
|
103
262
|
i {
|
|
104
263
|
font-size: 6px;
|
|
105
|
-
color:
|
|
264
|
+
color: $jv-text-soft;
|
|
106
265
|
margin-top: 1px;
|
|
107
266
|
}
|
|
108
267
|
|
|
109
|
-
// Child link
|
|
110
268
|
a {
|
|
111
269
|
text-decoration: none;
|
|
112
|
-
font-size:
|
|
113
|
-
color:
|
|
114
|
-
transition: color $jv-transition-fast;
|
|
270
|
+
font-size: $jv-font-size-sm;
|
|
271
|
+
color: $jv-text-main;
|
|
272
|
+
transition: color $jv-transition-fast;
|
|
115
273
|
|
|
116
|
-
// Focus state for accessibility
|
|
117
274
|
&:focus-visible {
|
|
118
275
|
outline: none;
|
|
119
276
|
color: $jv-primary;
|
|
@@ -123,7 +280,6 @@ li[component="categories/category"] .category-children {
|
|
|
123
280
|
}
|
|
124
281
|
}
|
|
125
282
|
|
|
126
|
-
// Hover state: blue dot + blue text
|
|
127
283
|
&:hover {
|
|
128
284
|
i {
|
|
129
285
|
color: $jv-primary;
|
|
@@ -134,3 +290,232 @@ li[component="categories/category"] .category-children {
|
|
|
134
290
|
}
|
|
135
291
|
}
|
|
136
292
|
}
|
|
293
|
+
|
|
294
|
+
// ===========================================================
|
|
295
|
+
// ACTIVITY BADGES
|
|
296
|
+
// ===========================================================
|
|
297
|
+
|
|
298
|
+
.category-activity-row {
|
|
299
|
+
margin-top: $jv-space-1;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
.activity-badge {
|
|
303
|
+
display: inline-flex;
|
|
304
|
+
align-items: center;
|
|
305
|
+
gap: $jv-space-1;
|
|
306
|
+
padding: $jv-space-1 $jv-space-2;
|
|
307
|
+
font-size: $jv-font-size-xs;
|
|
308
|
+
font-weight: 500;
|
|
309
|
+
color: $jv-text-soft;
|
|
310
|
+
background: $jv-bg;
|
|
311
|
+
border-radius: $jv-radius-pill;
|
|
312
|
+
transition: all $jv-transition-fast;
|
|
313
|
+
cursor: default;
|
|
314
|
+
|
|
315
|
+
i {
|
|
316
|
+
font-size: $jv-font-size-xs;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
&:hover {
|
|
320
|
+
transform: scale(1.02);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// Removed .active green styling - now uses default muted style for time badge
|
|
324
|
+
|
|
325
|
+
&.hot {
|
|
326
|
+
background: rgba($jv-warning, 0.12);
|
|
327
|
+
color: $jv-warning;
|
|
328
|
+
|
|
329
|
+
i {
|
|
330
|
+
color: $jv-warning;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
&.new {
|
|
335
|
+
background: $jv-primary-soft;
|
|
336
|
+
color: $jv-primary;
|
|
337
|
+
|
|
338
|
+
i {
|
|
339
|
+
color: $jv-primary;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// ===========================================================
|
|
345
|
+
// CATEGORY ICON ENHANCED (with glow effect)
|
|
346
|
+
// ===========================================================
|
|
347
|
+
|
|
348
|
+
.category-icon-enhanced {
|
|
349
|
+
position: relative;
|
|
350
|
+
|
|
351
|
+
&::after {
|
|
352
|
+
content: '';
|
|
353
|
+
position: absolute;
|
|
354
|
+
inset: -2px;
|
|
355
|
+
border-radius: inherit;
|
|
356
|
+
background: inherit;
|
|
357
|
+
opacity: 0.2;
|
|
358
|
+
z-index: -1;
|
|
359
|
+
filter: blur(4px);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// ===========================================================
|
|
364
|
+
// EMPTY STATE
|
|
365
|
+
// ===========================================================
|
|
366
|
+
|
|
367
|
+
.empty-state {
|
|
368
|
+
color: $jv-text-soft !important;
|
|
369
|
+
font-style: italic;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
.empty-category-state {
|
|
373
|
+
display: flex;
|
|
374
|
+
align-items: center;
|
|
375
|
+
height: 100%;
|
|
376
|
+
|
|
377
|
+
.empty-icon {
|
|
378
|
+
display: flex;
|
|
379
|
+
align-items: center;
|
|
380
|
+
justify-content: center;
|
|
381
|
+
width: 28px;
|
|
382
|
+
height: 28px;
|
|
383
|
+
border-radius: $jv-radius-pill;
|
|
384
|
+
background: $jv-bg;
|
|
385
|
+
color: $jv-text-soft;
|
|
386
|
+
font-size: $jv-font-size-sm;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
.empty-text {
|
|
390
|
+
font-size: $jv-font-size-xs;
|
|
391
|
+
color: $jv-text-soft;
|
|
392
|
+
font-weight: 500;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// ===========================================================
|
|
397
|
+
// SUBCATEGORY PILLS
|
|
398
|
+
// ===========================================================
|
|
399
|
+
|
|
400
|
+
.subcategory-pills {
|
|
401
|
+
margin-top: $jv-space-2;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
.subcategory-pill {
|
|
405
|
+
display: inline-flex;
|
|
406
|
+
align-items: center;
|
|
407
|
+
gap: $jv-space-2;
|
|
408
|
+
padding: $jv-space-1 $jv-space-3 $jv-space-1 $jv-space-1;
|
|
409
|
+
background: $jv-bg;
|
|
410
|
+
border: 1px solid transparent;
|
|
411
|
+
border-radius: $jv-radius-pill;
|
|
412
|
+
text-decoration: none;
|
|
413
|
+
transition: all $jv-transition-fast;
|
|
414
|
+
|
|
415
|
+
.pill-icon {
|
|
416
|
+
display: flex;
|
|
417
|
+
align-items: center;
|
|
418
|
+
justify-content: center;
|
|
419
|
+
width: 22px;
|
|
420
|
+
height: 22px;
|
|
421
|
+
border-radius: $jv-radius-pill;
|
|
422
|
+
color: white;
|
|
423
|
+
font-size: $jv-font-size-xs;
|
|
424
|
+
flex-shrink: 0;
|
|
425
|
+
|
|
426
|
+
i {
|
|
427
|
+
line-height: 1;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
.pill-name {
|
|
432
|
+
font-size: $jv-font-size-xs;
|
|
433
|
+
font-weight: 500;
|
|
434
|
+
color: $jv-text-main;
|
|
435
|
+
white-space: nowrap;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
&:hover {
|
|
439
|
+
background: $jv-surface;
|
|
440
|
+
border-color: var(--pill-color, $jv-border-subtle);
|
|
441
|
+
box-shadow: $jv-shadow-sm;
|
|
442
|
+
transform: translateY(-1px);
|
|
443
|
+
|
|
444
|
+
.pill-name {
|
|
445
|
+
color: var(--pill-color, $jv-primary);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
&:focus-visible {
|
|
450
|
+
outline: none;
|
|
451
|
+
box-shadow: $jv-focus-ring;
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
// ===========================================================
|
|
456
|
+
// ANIMATIONS
|
|
457
|
+
// ===========================================================
|
|
458
|
+
|
|
459
|
+
@keyframes pulse {
|
|
460
|
+
0%, 100% {
|
|
461
|
+
opacity: 1;
|
|
462
|
+
}
|
|
463
|
+
50% {
|
|
464
|
+
opacity: 0.6;
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
// ===========================================================
|
|
469
|
+
// RESPONSIVE ADJUSTMENTS
|
|
470
|
+
// ===========================================================
|
|
471
|
+
|
|
472
|
+
@media (max-width: 991px) {
|
|
473
|
+
li[component="categories/category"] {
|
|
474
|
+
padding: $jv-space-4;
|
|
475
|
+
|
|
476
|
+
.teaser {
|
|
477
|
+
margin-top: $jv-space-3;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
@media (max-width: 576px) {
|
|
483
|
+
ul.categories-list.list-unstyled {
|
|
484
|
+
gap: $jv-space-2;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
li[component="categories/category"] {
|
|
488
|
+
padding: $jv-space-4;
|
|
489
|
+
border-radius: $jv-radius-sm;
|
|
490
|
+
|
|
491
|
+
.title {
|
|
492
|
+
font-size: $jv-font-size-base;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
.description {
|
|
496
|
+
font-size: $jv-font-size-xs;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
.category-activity-row {
|
|
500
|
+
flex-wrap: wrap;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
.subcategory-pills {
|
|
505
|
+
gap: $jv-space-1 !important;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
.subcategory-pill {
|
|
509
|
+
padding: $jv-space-1 $jv-space-2 $jv-space-1 $jv-space-1;
|
|
510
|
+
|
|
511
|
+
.pill-icon {
|
|
512
|
+
width: 18px;
|
|
513
|
+
height: 18px;
|
|
514
|
+
font-size: $jv-font-size-xs;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
.pill-name {
|
|
518
|
+
font-size: $jv-font-size-xs;
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
}
|
package/scss/_topic.scss
CHANGED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
<!-- IMPORT partials/breadcrumbs-json-ld.tpl -->
|
|
2
|
+
{{{ if config.theme.enableBreadcrumbs }}}
|
|
3
|
+
<!-- IMPORT partials/breadcrumbs.tpl -->
|
|
4
|
+
{{{ end }}}
|
|
5
|
+
|
|
6
|
+
<div class="category-header d-flex flex-column gap-2">
|
|
7
|
+
<div class="d-flex gap-2 align-items-center mb-1 {{{ if config.theme.centerHeaderElements }}}justify-content-center{{{ end }}}">
|
|
8
|
+
{buildCategoryIcon(@value, "40px", "rounded-1 flex-shrink-0")}
|
|
9
|
+
<h1 class="tracking-tight fs-2 fw-semibold mb-0">{./name}</h1>
|
|
10
|
+
</div>
|
|
11
|
+
{{{ if ./descriptionParsed }}}
|
|
12
|
+
<div class="description text-secondary text-sm w-100 {{{ if config.theme.centerHeaderElements }}}text-center{{{ end }}} line-clamp-4 clamp-fade-4">
|
|
13
|
+
{./descriptionParsed}
|
|
14
|
+
</div>
|
|
15
|
+
{{{ end }}}
|
|
16
|
+
<!-- ActivityPub handle - hidden by default, can show via tooltip -->
|
|
17
|
+
{{{ if ./handleFull }}}
|
|
18
|
+
<div class="activitypub-handle d-none">
|
|
19
|
+
<p class="text-secondary text-sm fst-italic mb-0">
|
|
20
|
+
[[category:handle.description, {handleFull}]]
|
|
21
|
+
<a href="#" class="link-secondary" data-action="copy" data-clipboard-text="{handleFull}"><i class="fa fa-fw fa-copy" aria-hidden="true"></i></a>
|
|
22
|
+
</p>
|
|
23
|
+
</div>
|
|
24
|
+
{{{ end }}}
|
|
25
|
+
<div class="d-flex flex-wrap gap-2 {{{ if config.theme.centerHeaderElements }}}justify-content-center{{{ end }}}">
|
|
26
|
+
<span class="badge text-body border border-gray-300 stats text-xs">
|
|
27
|
+
<span title="{totalTopicCount}" class="fw-bold">{humanReadableNumber(totalTopicCount)}</span>
|
|
28
|
+
<span class="text-lowercase fw-normal">[[global:topics]]</span>
|
|
29
|
+
</span>
|
|
30
|
+
<span class="badge text-body border border-gray-300 stats text-xs">
|
|
31
|
+
<span title="{totalPostCount}" class="fw-bold">{humanReadableNumber(totalPostCount)}</span>
|
|
32
|
+
<span class="text-lowercase fw-normal">[[global:posts]]</span>
|
|
33
|
+
</span>
|
|
34
|
+
{{{ if !isNumber(cid) }}}
|
|
35
|
+
<a href="{./url}" class="badge text-body border border-gray-300 text-xs" data-ajaxify="false">
|
|
36
|
+
<span class="fw-normal">View Original</span>
|
|
37
|
+
<i class="fa fa-external-link"></i>
|
|
38
|
+
</a>
|
|
39
|
+
{{{ end }}}
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
|
|
43
|
+
{{{ if widgets.header.length }}}
|
|
44
|
+
<div data-widget-area="header">
|
|
45
|
+
{{{ each widgets.header }}}
|
|
46
|
+
{{widgets.header.html}}
|
|
47
|
+
{{{ end }}}
|
|
48
|
+
</div>
|
|
49
|
+
{{{ end }}}
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
<div class="row flex-fill mt-3">
|
|
53
|
+
<div class="category d-flex flex-column {{{if widgets.sidebar.length }}}col-lg-9 col-sm-12{{{ else }}}col-lg-12{{{ end }}}">
|
|
54
|
+
<!-- IMPORT partials/category/subcategory.tpl -->
|
|
55
|
+
{{{ if (topics.length || privileges.topics:create) }}}
|
|
56
|
+
<!-- IMPORT partials/topic-list-bar.tpl -->
|
|
57
|
+
{{{ end }}}
|
|
58
|
+
|
|
59
|
+
{{{ if (./inbox && (./hasFollowers == false)) }}}
|
|
60
|
+
<div class="alert alert-warning mb-4" id="category-no-followers" data-bs-toggle="dropdown" data-bs-target='[component="topic/watch"] button' aria-hidden="true">
|
|
61
|
+
<i class="fa fa-triangle-exclamation pe-2"></i>
|
|
62
|
+
[[category:no-followers]]
|
|
63
|
+
<a href="#" class="stretched-link"></a>
|
|
64
|
+
</div>
|
|
65
|
+
{{{ end }}}
|
|
66
|
+
|
|
67
|
+
{{{ if (!topics.length && privileges.topics:create) }}}
|
|
68
|
+
<div class="alert alert-info" id="category-no-topics">
|
|
69
|
+
[[category:no-topics]]
|
|
70
|
+
</div>
|
|
71
|
+
{{{ end }}}
|
|
72
|
+
|
|
73
|
+
<!-- IMPORT partials/topics_list.tpl -->
|
|
74
|
+
|
|
75
|
+
{{{ if config.usePagination }}}
|
|
76
|
+
<!-- IMPORT partials/paginator.tpl -->
|
|
77
|
+
{{{ end }}}
|
|
78
|
+
</div>
|
|
79
|
+
<div data-widget-area="sidebar" class="col-lg-3 col-sm-12 {{{ if !widgets.sidebar.length }}}hidden{{{ end }}}">
|
|
80
|
+
{{{ each widgets.sidebar }}}
|
|
81
|
+
{{widgets.sidebar.html}}
|
|
82
|
+
{{{ end }}}
|
|
83
|
+
</div>
|
|
84
|
+
</div>
|
|
85
|
+
<div data-widget-area="footer">
|
|
86
|
+
{{{each widgets.footer}}}
|
|
87
|
+
{{widgets.footer.html}}
|
|
88
|
+
{{{end}}}
|
|
89
|
+
</div>
|
|
90
|
+
|
|
91
|
+
{{{ if !config.usePagination }}}
|
|
92
|
+
<noscript>
|
|
93
|
+
<!-- IMPORT partials/paginator.tpl -->
|
|
94
|
+
</noscript>
|
|
95
|
+
{{{ end }}}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
<li component="categories/category" data-cid="{./cid}" class="category-card w-100 py-3 py-lg-4 gap-lg-0 gap-2 d-flex flex-column flex-lg-row align-items-start category-{./cid} {./unread-class}">
|
|
2
|
+
<meta itemprop="name" content="{./name}">
|
|
3
|
+
|
|
4
|
+
<div class="d-flex col-lg-7 gap-2 gap-lg-3">
|
|
5
|
+
<div class="flex-shrink-0">
|
|
6
|
+
{buildCategoryIcon(@value, "48px", "rounded-1 category-icon-enhanced")}
|
|
7
|
+
</div>
|
|
8
|
+
<div class="flex-grow-1 d-flex flex-wrap gap-1 me-0 me-lg-2">
|
|
9
|
+
<h2 class="title text-break fs-5 fw-semibold m-0 tracking-tight w-100">
|
|
10
|
+
<!-- IMPORT partials/categories/link.tpl -->
|
|
11
|
+
</h2>
|
|
12
|
+
{{{ if ./descriptionParsed }}}
|
|
13
|
+
<div class="description text-muted text-sm w-100">
|
|
14
|
+
{./descriptionParsed}
|
|
15
|
+
</div>
|
|
16
|
+
{{{ end }}}
|
|
17
|
+
|
|
18
|
+
<!-- Activity Badge Row -->
|
|
19
|
+
<div class="category-activity-row d-flex align-items-center gap-2 w-100 mt-1">
|
|
20
|
+
{{{ each ./posts }}}
|
|
21
|
+
{{{ if @first }}}
|
|
22
|
+
<span class="activity-badge" title="Last activity">
|
|
23
|
+
<i class="fa fa-clock-o"></i>
|
|
24
|
+
<span class="timeago" title="{./timestampISO}"></span>
|
|
25
|
+
</span>
|
|
26
|
+
{{{ end }}}
|
|
27
|
+
{{{ end }}}
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
{{{ if !config.hideSubCategories }}}
|
|
31
|
+
{{{ if ./children.length }}}
|
|
32
|
+
<div class="subcategory-pills d-flex flex-wrap gap-2 mt-2 w-100">
|
|
33
|
+
{{{ each ./children }}}
|
|
34
|
+
{{{ if !./isSection }}}
|
|
35
|
+
<a href="{{{ if ./link }}}{./link}{{{ else }}}{config.relative_path}/category/{./slug}{{{ end }}}" class="subcategory-pill" style="--pill-color: {./bgColor};">
|
|
36
|
+
<span class="pill-icon" style="background-color: {./bgColor};">
|
|
37
|
+
<i class="{./icon}"></i>
|
|
38
|
+
</span>
|
|
39
|
+
<span class="pill-name">{./name}</span>
|
|
40
|
+
</a>
|
|
41
|
+
{{{ end }}}
|
|
42
|
+
{{{ end }}}
|
|
43
|
+
</div>
|
|
44
|
+
{{{ end }}}
|
|
45
|
+
{{{ end }}}
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
{{{ if !./link }}}
|
|
49
|
+
<div class="d-flex col-lg-5 col-12 align-content-stretch">
|
|
50
|
+
<div class="meta stats-minimal d-none d-lg-flex col-4 gap-3 pe-3 text-muted align-items-center justify-content-end">
|
|
51
|
+
<div class="stat-item text-center">
|
|
52
|
+
<span class="stat-number" title="{./totalTopicCount}">{humanReadableNumber(./totalTopicCount, 0)}</span>
|
|
53
|
+
<span class="stat-label">topics</span>
|
|
54
|
+
</div>
|
|
55
|
+
<div class="stat-item text-center">
|
|
56
|
+
<span class="stat-number" title="{./totalPostCount}">{humanReadableNumber(./totalPostCount, 0)}</span>
|
|
57
|
+
<span class="stat-label">posts</span>
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
{{{ if !config.hideCategoryLastPost }}}
|
|
61
|
+
<div component="topic/teaser" class="teaser col-lg-8 col-12 {{{ if !config.theme.mobileTopicTeasers }}}d-none d-lg-block{{{ end }}}">
|
|
62
|
+
<!-- IMPORT partials/categories/lastpost.tpl -->
|
|
63
|
+
</div>
|
|
64
|
+
{{{ end }}}
|
|
65
|
+
</div>
|
|
66
|
+
{{{ end }}}
|
|
67
|
+
</li>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<div class="lastpost teaser-enhanced lh-sm h-100" style="--teaser-color: {./bgColor};">
|
|
2
|
+
{{{ each ./posts }}}
|
|
3
|
+
{{{ if @first }}}
|
|
4
|
+
<div component="category/posts" class="d-flex flex-column h-100 gap-2">
|
|
5
|
+
<div class="teaser-header d-flex align-items-center gap-2">
|
|
6
|
+
<a class="text-decoration-none avatar-tooltip" title="{./user.displayname}" href="{config.relative_path}/user/{./user.userslug}">{buildAvatar(posts.user, "24px", true)}</a>
|
|
7
|
+
<div class="teaser-meta">
|
|
8
|
+
<span class="teaser-user">{./user.displayname}</span>
|
|
9
|
+
<a class="permalink timeago teaser-time" href="{config.relative_path}/topic/{./topic.slug}{{{ if ./index }}}/{./index}{{{ end }}}" title="{./timestampISO}" aria-label="[[global:lastpost]]"></a>
|
|
10
|
+
</div>
|
|
11
|
+
</div>
|
|
12
|
+
<div class="teaser-content-wrapper position-relative flex-fill">
|
|
13
|
+
<div class="teaser-content text-break line-clamp-2">
|
|
14
|
+
{./content}
|
|
15
|
+
</div>
|
|
16
|
+
<a class="teaser-read-more" href="{config.relative_path}/topic/{./topic.slug}{{{ if ./index }}}/{./index}{{{ end }}}">Read more →</a>
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
{{{ end }}}
|
|
20
|
+
{{{ end }}}
|
|
21
|
+
|
|
22
|
+
{{{ if !./posts.length }}}
|
|
23
|
+
<div component="category/posts" class="ps-2 empty-category-state">
|
|
24
|
+
<div class="d-flex flex-column align-items-start gap-1">
|
|
25
|
+
<span class="empty-icon"><i class="fa fa-inbox"></i></span>
|
|
26
|
+
<span class="empty-text">Be the first to post</span>
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
{{{ end }}}
|
|
30
|
+
</div>
|
|
@@ -69,28 +69,37 @@
|
|
|
69
69
|
</div>
|
|
70
70
|
{{{ end }}}
|
|
71
71
|
|
|
72
|
-
<!--
|
|
72
|
+
<!-- Content with optional thumbnail (side by side when image exists) -->
|
|
73
73
|
{{{ if ./thumbs.length }}}
|
|
74
|
-
<
|
|
75
|
-
<
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
74
|
+
<div class="topic-media-row">
|
|
75
|
+
<div class="topic-media-text">
|
|
76
|
+
{{{ if ./teaser.content }}}
|
|
77
|
+
<div class="topic-teaser">
|
|
78
|
+
{./teaser.content}
|
|
79
|
+
</div>
|
|
80
|
+
{{{ end }}}
|
|
81
|
+
</div>
|
|
82
|
+
<a class="topic-thumbnail" href="{config.relative_path}/topic/{./slug}{{{ if ./bookmark }}}/{./bookmark}{{{ end }}}">
|
|
83
|
+
<img src="{./thumbs.0.url}" alt="" loading="lazy" />
|
|
84
|
+
{{{ if ./thumbs.1 }}}
|
|
85
|
+
<span class="thumb-count">+{subtract(./thumbs.length, 1)}</span>
|
|
86
|
+
{{{ end }}}
|
|
87
|
+
</a>
|
|
88
|
+
</div>
|
|
89
|
+
{{{ else }}}
|
|
90
|
+
<!-- Teaser/Preview Content (no image) -->
|
|
83
91
|
{{{ if ./teaser.content }}}
|
|
84
92
|
<div class="topic-teaser">
|
|
85
93
|
{./teaser.content}
|
|
86
94
|
</div>
|
|
87
95
|
{{{ end }}}
|
|
96
|
+
{{{ end }}}
|
|
88
97
|
|
|
89
98
|
<!-- Action Bar -->
|
|
90
99
|
<div class="topic-actions">
|
|
91
100
|
<a href="{config.relative_path}/topic/{./slug}" class="action-btn">
|
|
92
101
|
<i class="fa-regular fa-comment"></i>
|
|
93
|
-
<span>{humanReadableNumber(./postcount, 0)} Comments</span>
|
|
102
|
+
<span>{humanReadableNumber(./postcount, 0)} {{{ if (./postcount == 1) }}}Comment{{{ else }}}Comments{{{ end }}}</span>
|
|
94
103
|
</a>
|
|
95
104
|
<button class="action-btn share-btn" data-url="{config.relative_path}/topic/{./slug}">
|
|
96
105
|
<i class="fa fa-share"></i>
|