@okjavis/nodebb-theme-javis 2.5.3 → 3.0.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.
@@ -97,7 +97,7 @@ html.composing .composer .title-container {
97
97
  border-radius: $jv-radius-lg $jv-radius-lg 0 0 !important;
98
98
  }
99
99
 
100
- // Category selector
100
+ // Category selector button
101
101
  html.composing .composer .category-list-container {
102
102
  flex-shrink: 0 !important;
103
103
  display: block !important;
@@ -116,53 +116,152 @@ html.composing .composer .category-list-container {
116
116
  background: $jv-hover-bg !important;
117
117
  }
118
118
  }
119
+ }
120
+ }
119
121
 
120
- .dropdown-menu {
121
- min-width: 280px !important;
122
- max-height: 320px !important;
123
- overflow-y: auto !important;
124
- padding: $jv-space-2 !important;
122
+ // ===========================================================
123
+ // CATEGORY DROPDOWN - Clean flat list (like reference image)
124
+ // Targeting exact DOM structure from DevTools
125
+ // ===========================================================
125
126
 
126
- // Fix category list spacing
127
- .category-dropdown-menu {
128
- margin: 0 !important;
129
- padding: 0 !important;
130
- }
127
+ // The dropdown container
128
+ div.dropdown-menu.p-1.show {
129
+ min-width: 280px !important;
130
+ max-width: 320px !important;
131
+ padding: $jv-space-2 0 !important;
132
+ border: 1px solid $jv-border-subtle !important;
133
+ border-radius: $jv-radius-sm !important;
134
+ box-shadow: $jv-shadow-lg !important;
135
+ background: $jv-surface !important;
136
+ }
131
137
 
132
- // Category items inside dropdown
133
- li.category {
134
- margin: 0 !important;
135
- padding: 0 !important;
136
-
137
- a.dropdown-item {
138
- display: flex !important;
139
- align-items: center !important;
140
- gap: $jv-space-2 !important;
141
- padding: $jv-space-2 $jv-space-3 !important;
142
- margin: 2px 0 !important;
143
- font-size: $jv-font-size-sm !important;
144
- color: $jv-text-main !important;
145
- border-radius: $jv-radius-xs !important;
146
- white-space: nowrap !important;
147
- overflow: hidden !important;
148
- text-overflow: ellipsis !important;
149
-
150
- &:hover {
151
- background: $jv-hover-bg !important;
152
- }
153
-
154
- // Category icon
155
- .category-item {
156
- display: inline-flex !important;
157
- align-items: center !important;
158
- gap: $jv-space-2 !important;
159
- }
160
- }
161
- }
138
+ // Search input section
139
+ div[component="category-selector-search"] {
140
+ padding: $jv-space-2 $jv-space-3 $jv-space-3 $jv-space-3 !important;
141
+ margin: 0 !important;
142
+ border-bottom: none !important;
143
+
144
+ .form-control {
145
+ width: 100% !important;
146
+ height: 36px !important;
147
+ padding: 0 $jv-space-3 !important;
148
+ font-size: $jv-font-size-sm !important;
149
+ font-weight: 400 !important;
150
+ color: $jv-text-main !important;
151
+ border: 1px solid $jv-border-subtle !important;
152
+ border-radius: $jv-radius-xs !important;
153
+ background: $jv-surface !important;
154
+
155
+ &:focus {
156
+ border-color: $jv-primary !important;
157
+ box-shadow: $jv-focus-ring !important;
158
+ outline: none !important;
162
159
  }
160
+
161
+ &::placeholder {
162
+ color: $jv-text-soft !important;
163
+ }
164
+ }
165
+
166
+ hr {
167
+ display: none !important;
163
168
  }
164
169
  }
165
170
 
171
+ // The category list UL - exact class from DOM
172
+ ul.category-dropdown-menu.ghost-scrollbar {
173
+ margin: 0 !important;
174
+ padding: 0 !important;
175
+ max-height: 320px !important;
176
+ overflow-y: auto !important;
177
+ overflow-x: hidden !important;
178
+ list-style: none !important;
179
+
180
+ // Scrollbar
181
+ &::-webkit-scrollbar {
182
+ width: 6px;
183
+ }
184
+ &::-webkit-scrollbar-track {
185
+ background: transparent;
186
+ }
187
+ &::-webkit-scrollbar-thumb {
188
+ background: rgba(0, 0, 0, 0.15);
189
+ border-radius: 3px;
190
+ }
191
+ }
192
+
193
+ // Each category LI - exact structure: li.category with role="presentation"
194
+ li[role="presentation"].category {
195
+ margin: 0 !important;
196
+ padding: 0 !important;
197
+ list-style: none !important;
198
+ border: none !important;
199
+ background: none !important;
200
+ background-color: transparent !important;
201
+ box-shadow: none !important;
202
+ }
203
+
204
+ // The anchor - reduce spacing and remove border/card styling
205
+ li.category > a.dropdown-item,
206
+ li.category > a.dropdown-item.rounded-1 {
207
+ padding: $jv-space-1 $jv-space-3 !important;
208
+ margin: 2px $jv-space-2 !important;
209
+ border: none !important;
210
+ border-radius: $jv-radius-xs !important;
211
+ background: transparent !important;
212
+ box-shadow: none !important;
213
+
214
+ &:hover {
215
+ background: $jv-hover-bg !important;
216
+ }
217
+ }
218
+
219
+ // Sub-categories indentation
220
+ li.category[data-parent-cid]:not([data-parent-cid="0"]) > a.dropdown-item {
221
+ padding-left: 36px !important;
222
+ }
223
+
224
+ // Category icon
225
+ li.category a.dropdown-item [component="category/icon"] {
226
+ width: 24px !important;
227
+ height: 24px !important;
228
+ min-width: 24px !important;
229
+ border-radius: 50% !important;
230
+ display: flex !important;
231
+ align-items: center !important;
232
+ justify-content: center !important;
233
+ font-size: $jv-font-size-xs !important;
234
+ flex-shrink: 0 !important;
235
+ box-shadow: none !important;
236
+ }
237
+
238
+ // Category name text
239
+ li.category a.dropdown-item > span:last-child {
240
+ font-size: $jv-font-size-sm !important;
241
+ font-weight: 400 !important;
242
+ color: $jv-text-main !important;
243
+ white-space: nowrap !important;
244
+ overflow: hidden !important;
245
+ text-overflow: ellipsis !important;
246
+ }
247
+
248
+ // Disabled categories
249
+ li.category.disabled > a.dropdown-item > span:last-child {
250
+ color: $jv-text-soft !important;
251
+ }
252
+
253
+ // No matches message
254
+ li[component="category/no-matches"].hidden {
255
+ display: none !important;
256
+ }
257
+
258
+ li[component="category/no-matches"]:not(.hidden) {
259
+ padding: $jv-space-4 !important;
260
+ text-align: center !important;
261
+ color: $jv-text-soft !important;
262
+ font-size: $jv-font-size-sm !important;
263
+ }
264
+
166
265
  // Title input
167
266
  html.composing .composer [data-component="composer/title"] {
168
267
  flex: 1 !important;
package/scss/_feed.scss CHANGED
@@ -3,6 +3,33 @@
3
3
  // Styles for nodebb-plugin-feed (/feed route)
4
4
  // ===========================================================
5
5
 
6
+ // ===========================================================
7
+ // AVATAR SIZE OVERRIDE - Force 32px avatars on feed page
8
+ // ===========================================================
9
+ .feed {
10
+ // Composer prompt avatar
11
+ .composer-prompt-avatar span.avatar,
12
+ .composer-prompt-avatar .avatar {
13
+ width: 32px !important;
14
+ height: 32px !important;
15
+ min-width: 32px !important;
16
+ min-height: 32px !important;
17
+ font-size: 14px !important;
18
+ line-height: 32px !important;
19
+ }
20
+
21
+ // Feed card desktop avatar (next to content)
22
+ li.posts-list-item .d-none.d-lg-block span.avatar,
23
+ li.posts-list-item .d-none.d-lg-block .avatar {
24
+ width: 32px !important;
25
+ height: 32px !important;
26
+ min-width: 32px !important;
27
+ min-height: 32px !important;
28
+ font-size: 14px !important;
29
+ line-height: 32px !important;
30
+ }
31
+ }
32
+
6
33
  // ===========================================================
7
34
  // HIDE CATEGORIES WIDGET ON FEED PAGE
8
35
  // The categories list widget is not relevant on the feed page
@@ -73,24 +100,38 @@
73
100
  .composer-prompt-avatar {
74
101
  flex-shrink: 0;
75
102
 
103
+ // Override all avatar types
104
+ img,
105
+ span.avatar,
76
106
  .avatar {
77
- width: 48px !important;
78
- height: 48px !important;
107
+ --avatar-size: 32px !important;
108
+ width: 32px !important;
109
+ height: 32px !important;
110
+ min-width: 32px !important;
111
+ min-height: 32px !important;
112
+ max-width: 32px !important;
113
+ max-height: 32px !important;
79
114
  border-radius: 50% !important;
80
- object-fit: cover;
81
- border: 2px solid rgba(0, 0, 0, 0.05);
115
+ font-size: 14px !important;
116
+ line-height: 32px !important;
82
117
  }
83
118
 
119
+ // Placeholder avatar for logged-out users
84
120
  .avatar-placeholder {
85
- width: 48px;
86
- height: 48px;
87
- border-radius: 50%;
88
- background: linear-gradient(135deg, $jv-primary-soft 0%, rgba(0, 81, 255, 0.2) 100%);
89
- display: flex;
121
+ width: 32px !important;
122
+ height: 32px !important;
123
+ min-width: 32px !important;
124
+ min-height: 32px !important;
125
+ border-radius: 50% !important;
126
+ background: $jv-border-subtle;
127
+ display: flex !important;
90
128
  align-items: center;
91
129
  justify-content: center;
92
- color: $jv-primary;
93
- font-size: 18px;
130
+ color: $jv-text-soft;
131
+
132
+ i {
133
+ font-size: 14px;
134
+ }
94
135
  }
95
136
  }
96
137
 
@@ -182,12 +223,12 @@
182
223
  .composer-prompt-avatar {
183
224
  .avatar,
184
225
  .avatar-placeholder {
185
- width: 40px !important;
186
- height: 40px !important;
226
+ width: 32px !important;
227
+ height: 32px !important;
187
228
  }
188
229
 
189
230
  .avatar-placeholder {
190
- font-size: 16px;
231
+ font-size: 14px;
191
232
  }
192
233
  }
193
234
 
@@ -277,29 +318,26 @@
277
318
  .feed li[component="post"].posts-list-item {
278
319
  background: $jv-surface !important;
279
320
  border: 1px solid $jv-border-subtle !important;
280
- border-radius: $jv-radius-sm !important; // 8px - shadcn standard
281
- margin-bottom: $jv-space-2 !important; // 8dp grid
282
- box-shadow: $jv-shadow-sm !important; // shadcn subtle shadow
283
- overflow: hidden;
284
- transition: $jv-transition-shadow, border-color $jv-transition-fast; // Modern smooth transitions
321
+ border-radius: $jv-radius-sm !important;
322
+ margin-bottom: $jv-space-2 !important;
323
+ box-shadow: $jv-shadow-sm !important;
324
+ overflow: hidden !important;
325
+ transition: $jv-transition-shadow, border-color $jv-transition-fast;
285
326
 
286
327
  &:hover {
287
- box-shadow: $jv-shadow-md !important; // shadcn hover shadow
288
- border-color: $jv-border-strong !important; // Subtle border darkening
328
+ box-shadow: $jv-shadow-md !important;
329
+ border-color: $jv-border-strong !important;
289
330
  }
290
331
 
291
- // Focus state for accessibility
292
332
  &:focus-within {
293
333
  outline: none;
294
334
  box-shadow: $jv-shadow-md, $jv-focus-ring !important;
295
335
  }
296
336
 
297
- // Deleted state
298
337
  &.deleted {
299
338
  opacity: 0.5;
300
339
  }
301
340
 
302
- // Scheduled state
303
341
  &.scheduled {
304
342
  border-left: 3px solid #f59e0b;
305
343
  }
@@ -313,19 +351,19 @@
313
351
  padding: 0 !important;
314
352
 
315
353
  .overflow-hidden {
316
- border-radius: $jv-radius-md $jv-radius-md 0 0 !important; // Match card radius
317
- max-height: 280px !important; // Reduced from 350px - more balanced ratio
318
- background: rgba(0, 0, 0, 0.02); // Subtle background for letterboxing
354
+ border-radius: $jv-radius-md !important;
355
+ max-height: 280px !important;
356
+ background: rgba(0, 0, 0, 0.02);
319
357
 
320
358
  img {
321
359
  width: 100%;
322
- height: 280px; // Fixed height for consistency
323
- object-fit: contain; // Prevent stretching, maintain aspect ratio
360
+ height: 280px;
361
+ object-fit: contain;
324
362
  }
325
363
  }
326
364
 
327
- // Hide additional thumbnails - only show main image in feed
328
- .position-absolute {
365
+ // Hide the overlay with image count
366
+ > .position-absolute {
329
367
  display: none !important;
330
368
  }
331
369
  }
@@ -335,30 +373,26 @@
335
373
  // POST CONTENT AREA
336
374
  // ===========================================================
337
375
  .feed li[component="post"].posts-list-item {
376
+ // Change layout to vertical stack instead of horizontal
338
377
  > .d-flex.gap-2.p-3 {
339
- padding: $jv-space-4 $jv-space-3 !important; // 16dp vertical, 12dp horizontal - Material grid
340
- gap: $jv-space-3 !important; // 12dp spacing
378
+ padding: $jv-space-4 !important; // 16dp all sides - equal spacing
379
+ flex-direction: column !important; // Stack vertically
380
+ gap: 0 !important; // Remove gap, we'll use margins
341
381
 
342
382
  @media (max-width: 768px) {
343
- padding: $jv-space-3 $jv-space-2 !important; // 12dp vertical, 8dp horizontal on mobile
383
+ padding: $jv-space-3 !important; // 12dp all sides on mobile
344
384
  }
345
385
  }
346
386
 
347
- // Avatar
348
- .d-none.d-lg-block {
349
- .avatar,
350
- img[class*="avatar"] {
351
- width: 48px !important; // 48dp - Material standard avatar size
352
- height: 48px !important;
353
- border-radius: 50% !important;
354
- object-fit: cover;
355
- border: 2px solid rgba(0, 0, 0, 0.05);
356
- }
387
+ // Hide the separate avatar column - we'll show avatar inline with author
388
+ > .d-flex.gap-2.p-3 > .d-none.d-lg-block {
389
+ display: none !important;
357
390
  }
358
391
 
359
- // Post body
392
+ // Post body - full width, contains everything
360
393
  .post-body {
361
394
  gap: $jv-space-2 !important; // 8dp - Material grid
395
+ width: 100% !important;
362
396
  }
363
397
  }
364
398
 
@@ -385,27 +419,39 @@
385
419
  // ===========================================================
386
420
  .feed li[component="post"].posts-list-item {
387
421
  .post-info {
388
- font-size: 14px !important; // Slightly larger for readability
389
- color: $jv-text-soft; // Lighter for hierarchy
390
- gap: $jv-space-3 !important; // More spacing between elements
422
+ font-size: 14px !important;
423
+ color: $jv-text-soft;
424
+ gap: $jv-space-2 !important;
425
+ display: flex !important;
426
+ align-items: center !important;
427
+ margin-bottom: $jv-space-2 !important; // Space before title
391
428
 
392
429
  .post-author {
430
+ display: flex !important;
431
+ align-items: center !important;
432
+ gap: $jv-space-2 !important;
433
+
393
434
  a {
394
- color: $jv-text-soft; // More subtle - not competing with title
395
- font-weight: 400; // Normal weight
435
+ color: $jv-text-soft;
436
+ font-weight: 400;
396
437
  font-size: 14px;
397
438
 
398
439
  &:hover {
399
440
  color: $jv-primary;
400
441
  }
401
- }
402
442
 
403
- // Mobile avatar
404
- .avatar,
405
- img[class*="avatar"] {
406
- width: 18px !important;
407
- height: 18px !important;
408
- border-radius: 50% !important;
443
+ // Avatar inside the anchor - sized correctly
444
+ .avatar,
445
+ span.avatar {
446
+ width: 32px !important;
447
+ height: 32px !important;
448
+ min-width: 32px !important;
449
+ min-height: 32px !important;
450
+ border-radius: 50% !important;
451
+ flex-shrink: 0 !important;
452
+ font-size: 13px !important;
453
+ line-height: 32px !important;
454
+ }
409
455
  }
410
456
  }
411
457
 
@@ -421,6 +467,18 @@
421
467
  }
422
468
  }
423
469
 
470
+ // Override Bootstrap's d-lg-none to show avatar on desktop
471
+ // Must use same media query breakpoint to override
472
+ @media (min-width: 992px) {
473
+ .feed li[component="post"].posts-list-item {
474
+ .post-info .post-author a.d-inline.d-lg-none {
475
+ display: inline-flex !important;
476
+ align-items: center !important;
477
+ gap: $jv-space-2 !important;
478
+ }
479
+ }
480
+ }
481
+
424
482
  // ===========================================================
425
483
  // POST CONTENT
426
484
  // ===========================================================
@@ -590,20 +648,19 @@
590
648
  // ===========================================================
591
649
  .feed li[component="post"].posts-list-item {
592
650
  hr {
593
- border-color: $jv-border-subtle !important;
594
- margin: $jv-space-2 0 !important; // Tighter - 4px
595
- opacity: 1;
651
+ display: none !important; // Hide divider line between content and image
596
652
  }
597
653
  }
598
654
 
599
655
  // ===========================================================
600
656
  // ACTION BAR (Comments, Bookmark, Upvote, Reply)
657
+ // Now a separate element in the template (not nested in .post-body)
601
658
  // ===========================================================
602
659
  .feed li[component="post"].posts-list-item {
603
- .d-flex.justify-content-between:last-child {
604
- margin: 0 (-$jv-space-2);
605
- padding-top: $jv-space-4; // More padding - 8px
606
- border-top: 1px solid rgba(0, 0, 0, 0.06); // Slightly more visible separator
660
+ // Action bar - now a direct child of the post card
661
+ .feed-action-bar {
662
+ background: $jv-surface !important;
663
+ border-radius: 0 0 $jv-radius-sm $jv-radius-sm; // Match card's bottom corners
607
664
 
608
665
  .btn-link {
609
666
  display: inline-flex;
package/scss/_header.scss CHANGED
@@ -5,7 +5,7 @@
5
5
  // Inspired by: Slack, Linear, Notion, GitHub
6
6
 
7
7
  // ===========================================================
8
- // BRAND CONTAINER (Top Bar)
8
+ // BRAND CONTAINER (Top Bar) - Reddit-style compact header
9
9
  // ===========================================================
10
10
  .brand-container {
11
11
  position: sticky;
@@ -14,8 +14,8 @@
14
14
  background: $jv-surface;
15
15
  border-bottom: 1px solid $jv-border-subtle;
16
16
  margin: 0 !important; // No margins - ever
17
- padding: $jv-space-3 $jv-space-4 !important; // 12px vertical, 16px horizontal
18
- min-height: 64px; // 12px top + 40px search + 12px bottom
17
+ padding: $jv-space-2 $jv-space-4 !important; // 8px vertical, 16px horizontal (tighter)
18
+ min-height: 56px; // Compact like Reddit (was 64px)
19
19
  max-width: 100% !important; // Override container-lg max-width
20
20
  width: 100% !important; // Full width always
21
21
  display: flex;
@@ -79,7 +79,7 @@
79
79
  }
80
80
 
81
81
  // ===========================================================
82
- // SEARCH BAR - Centered, Prominent
82
+ // SEARCH BAR - Shifted left to align with feed content
83
83
  // ===========================================================
84
84
  [data-widget-area="brand-header"] {
85
85
  flex: 1;
@@ -87,6 +87,9 @@
87
87
  justify-content: center;
88
88
  align-items: center;
89
89
  padding: 0 $jv-space-4 !important;
90
+ // Shift the entire search area to the left
91
+ margin-left: -100px !important;
92
+ margin-right: 100px !important;
90
93
  }
91
94
 
92
95
  // Search widget in header
@@ -145,7 +148,7 @@
145
148
  padding-left: $jv-space-2;
146
149
  font-size: $jv-font-size-base;
147
150
  color: $jv-text-main;
148
- height: 40px; // Consistent height
151
+ height: 36px; // Slightly shorter for compact header
149
152
 
150
153
  // Placeholder styling
151
154
  &::placeholder {
@@ -167,9 +170,9 @@
167
170
  // Search submit button (blue button)
168
171
  .btn-primary,
169
172
  .btn[type="submit"] {
170
- height: 40px;
171
- min-width: 40px;
172
- padding: 0 $jv-space-4;
173
+ height: 36px; // Match input height
174
+ min-width: 36px;
175
+ padding: 0 $jv-space-3;
173
176
  border-radius: 0 $jv-radius-pill $jv-radius-pill 0 !important;
174
177
  display: flex;
175
178
  align-items: center;
@@ -240,7 +243,7 @@
240
243
  @media (max-width: 991px) {
241
244
  .brand-container {
242
245
  // On tablet/mobile, maintain proper spacing
243
- min-height: 56px !important;
246
+ min-height: 52px !important; // Even more compact on mobile
244
247
  margin: 0 !important;
245
248
  padding: $jv-space-2 0 !important;
246
249
 
@@ -88,24 +88,44 @@
88
88
  }
89
89
 
90
90
  // Auth section for logged-out users
91
- .sidebar-auth-section {
91
+ // Structure: .sidebar-auth-section.mx-2.mb-2 > .nav-item > .nav-link
92
+ // Skins structure: .dropend.m-2 > .nav-link
93
+ // To match Skins: container has no margin, nav-item gets m-2
94
+ .sidebar-auth-section.mx-2.mb-2 {
92
95
  border-top: 1px solid $jv-border-subtle;
93
96
  padding-top: $jv-space-4;
94
97
  margin-top: auto;
98
+ margin-left: 0 !important;
99
+ margin-right: 0 !important;
100
+ margin-bottom: 0 !important;
101
+ }
102
+
103
+ .sidebar-auth-section {
104
+ .nav-item {
105
+ // Match Skins .dropend.m-2
106
+ margin: 8px !important;
107
+ }
95
108
 
96
109
  .nav-link {
97
- padding: $jv-space-2 $jv-space-4;
98
110
  border-radius: $jv-radius-sm;
99
111
  font-size: $jv-font-size-sm;
100
- color: $jv-text-main;
112
+ color: $jv-text-muted;
113
+ font-weight: 600;
101
114
 
102
115
  &:hover {
103
- background-color: rgba(0, 0, 0, 0.04);
116
+ background-color: rgba(0, 81, 255, 0.06);
104
117
  color: $jv-primary;
105
118
  }
106
119
 
107
120
  i {
108
- color: $jv-text-muted;
121
+ width: 1.25em;
122
+ text-align: center;
123
+ color: inherit;
124
+ }
125
+
126
+ .nav-text {
127
+ padding-left: 8px !important;
128
+ padding-right: 8px !important;
109
129
  }
110
130
  }
111
131
  }