@okjavis/nodebb-theme-javis 1.5.1 → 1.7.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@okjavis/nodebb-theme-javis",
3
- "version": "1.5.1",
3
+ "version": "1.7.0",
4
4
  "description": "Modern, premium NodeBB theme for JAVIS Community - Extends Harmony with custom styling",
5
5
  "main": "theme.js",
6
6
  "scripts": {
package/scss/_base.scss CHANGED
@@ -30,6 +30,7 @@ nav[component="sidebar/left"] {
30
30
  // Sidebar toggle container - push to bottom
31
31
  .sidebar-toggle-container {
32
32
  margin-top: auto !important; // Push to bottom
33
+ width: 100% !important;
33
34
  }
34
35
  }
35
36
 
@@ -40,8 +41,8 @@ nav[component="sidebar/left"] {
40
41
  padding: 0 20px; // Reddit-style horizontal padding
41
42
  justify-content: center; // Center the columns
42
43
 
43
- // Equal gap between columns (Reddit uses ~16-20px)
44
- gap: 20px;
44
+ // Gap between columns
45
+ gap: $jv-space-8; // 32px
45
46
 
46
47
  // Adjust column widths for better proportions
47
48
  > [data-widget-area="left"] {
package/scss/_cards.scss CHANGED
@@ -279,6 +279,20 @@
279
279
  gap: $jv-space-3; // 12dp - Material grid
280
280
  padding-top: $jv-space-3; // 12dp - Material grid
281
281
  margin-top: auto;
282
+ border-top: none !important; // Remove any border-top
283
+
284
+ // Hide hr element if present
285
+ hr {
286
+ display: none !important;
287
+ }
288
+ }
289
+
290
+ // Hide hr elements within topic cards globally
291
+ .topic-card hr,
292
+ .topic-content hr,
293
+ li[component="post"] hr,
294
+ [component="post"] hr {
295
+ display: none !important;
282
296
  }
283
297
 
284
298
  .action-btn {
package/scss/_feed.scss CHANGED
@@ -3,6 +3,24 @@
3
3
  // Styles for nodebb-plugin-feed (/feed route)
4
4
  // ===========================================================
5
5
 
6
+ // ===========================================================
7
+ // HIDE NEW TOPIC BUTTON AND ALL CATEGORIES ROW
8
+ // ===========================================================
9
+ // Hide New Topic button
10
+ // #new_topic,
11
+ // .btn[href*="/compose"],
12
+ // button[data-action="newTopic"],
13
+ // a[href*="/compose"] {
14
+ // display: none !important;
15
+ // }
16
+
17
+ // // Hide All categories row
18
+ // .category-selector-container,
19
+ // [component="category/dropdown"],
20
+ // .d-flex.justify-content-between.py-2.mb-2 {
21
+ // display: none !important;
22
+ // }
23
+
6
24
  // ===========================================================
7
25
  // FEED CONTAINER
8
26
  // ===========================================================
@@ -10,12 +28,12 @@
10
28
  // No max-width - let Bootstrap grid handle width
11
29
  // Already inside col-lg-9 which provides proper constraints
12
30
 
13
- // Header controls row
31
+ // Header controls row (keeping for reference, but hidden above)
14
32
  .d-flex.justify-content-between.py-2.mb-2 {
15
33
  padding: $jv-space-4 0 !important;
16
34
  margin-bottom: $jv-space-6 !important;
17
35
 
18
- // New Topic button
36
+ // New Topic button (hidden above)
19
37
  #new_topic,
20
38
  .btn-primary {
21
39
  font-weight: 600;
@@ -51,11 +51,6 @@
51
51
  border-right: 1px solid $jv-border-subtle;
52
52
  padding-top: 0 !important; // Remove top padding so logo sits at top edge
53
53
 
54
- // Main navigation list
55
- #main-nav {
56
- // No gap class - we control spacing per nav-item instead
57
- }
58
-
59
54
  // Nav items - proper spacing between items
60
55
  .nav-item {
61
56
  margin-bottom: $jv-space-2; // 4px between nav items - compact like Slack/Discord
@@ -156,7 +151,6 @@
156
151
  div[data-widget-area] {
157
152
  display: flex;
158
153
  flex-direction: column;
159
- gap: $jv-space-6;
160
154
  }
161
155
 
162
156
  // Individual widget card
@@ -178,129 +172,6 @@ div[data-widget-area] {
178
172
  }
179
173
  }
180
174
 
181
- // Widget titles
182
- .widget-title,
183
- div[data-widget-area] h5,
184
- div[data-widget-area] h6,
185
- div[data-widget-area="right"] h5,
186
- div[data-widget-area="right"] h8 {
187
- font-size: 14px;
188
- font-weight: 700;
189
- margin-bottom: $jv-space-6;
190
- color: $jv-text-main;
191
- text-transform: uppercase;
192
- letter-spacing: 0.3px;
193
- }
194
-
195
- // ===========================================================
196
- // TRENDING TAGS
197
- // ===========================================================
198
-
199
- .popular-tags {
200
- gap: 6px;
201
-
202
- .tag-list > div {
203
- background: $jv-surface;
204
- border: 1px solid $jv-border-subtle;
205
- border-radius: 10px;
206
- padding: 10px 12px;
207
- font-size: 14px;
208
- color: $jv-text-main;
209
- display: flex;
210
- flex-direction: column;
211
- gap: 2px;
212
- cursor: pointer;
213
- transition: border-color $jv-transition-fast, background-color $jv-transition-fast; // Modern transitions
214
-
215
- &:hover {
216
- border-color: $jv-border-strong; // Consistent border
217
- background: $jv-hover-bg; // Consistent hover state
218
- }
219
-
220
- // Focus state for accessibility
221
- &:focus-visible {
222
- outline: none;
223
- box-shadow: $jv-focus-ring;
224
- }
225
-
226
- small {
227
- color: $jv-text-muted;
228
- font-size: $jv-font-size-xs;
229
- }
230
- }
231
- }
232
-
233
- // ===========================================================
234
- // TRENDING NOW
235
- // ===========================================================
236
-
237
- #recent_posts {
238
- display: flex;
239
- flex-direction: column;
240
- gap: 10px;
241
- margin-top: $jv-space-6;
242
-
243
- li.widget-posts {
244
- background: $jv-surface;
245
- border: 1px solid rgba(0,0,0,0.05);
246
- border-radius: $jv-radius-md;
247
- padding: 10px 14px;
248
- display: flex;
249
- flex-direction: column;
250
- gap: $jv-space-4;
251
- transition: $jv-transition-shadow, border-color $jv-transition-fast; // Modern transitions
252
-
253
- &:hover {
254
- border-color: $jv-border-strong; // Consistent border
255
- box-shadow: $jv-shadow-sm; // shadcn subtle shadow
256
- }
257
-
258
- // Focus state for accessibility
259
- &:focus-within {
260
- outline: none;
261
- box-shadow: $jv-shadow-md, $jv-focus-ring;
262
- }
263
-
264
- // Meta info
265
- .d-flex.gap-2,
266
- .timeago {
267
- font-size: $jv-font-size-xs;
268
- color: $jv-text-muted;
269
- }
270
-
271
- // Title inside mini post
272
- a {
273
- font-size: 14px;
274
- font-weight: 500;
275
- color: $jv-text-main;
276
- text-decoration: none;
277
- line-height: $jv-line-height-tight;
278
-
279
- &:hover {
280
- color: $jv-primary;
281
- }
282
- }
283
-
284
- // 2-line clamp for content preview
285
- p,
286
- .content {
287
- display: -webkit-box;
288
- -webkit-line-clamp: 2;
289
- -webkit-box-orient: vertical;
290
- overflow: hidden;
291
- font-size: $jv-font-size-sm;
292
- color: $jv-text-muted;
293
- margin: 0;
294
- }
295
-
296
- // Read more alignment
297
- a.stretched-link {
298
- font-size: $jv-font-size-xs;
299
- color: $jv-primary;
300
- }
301
- }
302
- }
303
-
304
175
  // ===========================================================
305
176
  // SEARCH WIDGET
306
177
  // ===========================================================
@@ -637,11 +508,35 @@ div[data-widget-area="right"] h8 {
637
508
  // ===========================================================
638
509
  // RIGHT SIDEBAR WIDGET AREA (Reddit-style)
639
510
  // ===========================================================
640
- div[data-widget-area="sidebar"],
641
- .col-lg-3[data-widget-area="sidebar"] {
511
+ div[data-widget-area="right"],
512
+ .col-lg-3.col-sm-12 {
642
513
  display: flex;
643
514
  flex-direction: column;
644
- gap: $jv-space-6;
515
+
516
+ // Sticky positioning - stays visible when scrolling
517
+ position: sticky;
518
+ top: 36px; // Adjust based on your header height
519
+ align-self: flex-start;
520
+ max-height: calc(100vh - 100px); // Account for header + padding
521
+ overflow-y: auto; // Allow scrolling if content is too tall
522
+
523
+ // Smooth scrollbar styling (webkit browsers)
524
+ &::-webkit-scrollbar {
525
+ width: 6px;
526
+ }
527
+
528
+ &::-webkit-scrollbar-track {
529
+ background: transparent;
530
+ }
531
+
532
+ &::-webkit-scrollbar-thumb {
533
+ background: rgba(0, 0, 0, 0.15);
534
+ border-radius: 3px;
535
+
536
+ &:hover {
537
+ background: rgba(0, 0, 0, 0.25);
538
+ }
539
+ }
645
540
 
646
541
  // Widget card container
647
542
  > div {
@@ -651,219 +546,310 @@ div[data-widget-area="sidebar"],
651
546
  overflow: hidden;
652
547
  }
653
548
 
654
- // Widget header/title
549
+ // Widget header/title - clean and simple
655
550
  h5, h6, .widget-title {
656
- font-size: 12px !important;
551
+ font-size: 11px !important;
657
552
  font-weight: 700 !important;
658
553
  text-transform: uppercase;
659
554
  letter-spacing: 0.5px;
660
555
  color: $jv-text-soft;
661
- padding: $jv-space-6 $jv-space-6 $jv-space-4;
556
+ padding: $jv-space-4 $jv-space-4 $jv-space-4 $jv-space-4;
662
557
  margin: 0 !important;
663
- border-bottom: 1px solid $jv-border-subtle;
664
- background: rgba(0, 0, 0, 0.015);
558
+ border-bottom: none !important; // Removed border
559
+ }
560
+
561
+ // Add spacing between widgets
562
+ > div + div {
563
+ margin-top: $jv-space-4;
665
564
  }
666
565
  }
667
566
 
668
567
  // ===========================================================
669
- // POPULAR TAGS WIDGET (Sidebar)
568
+ // TRENDING TAGS WIDGET (Sidebar) - Pill-style flowing tags
670
569
  // ===========================================================
671
- div[data-widget-area="sidebar"] {
672
- .popular-tags,
673
- [class*="tag"] {
674
- padding: $jv-space-4;
570
+ div[data-widget-area="right"] {
571
+ // Remove outer card for tags widget - let it flow directly
572
+ > div:has(.popular-tags) {
573
+ background: transparent !important;
574
+ border: none !important;
575
+ border-radius: 0 !important;
576
+ overflow: visible !important;
675
577
 
676
- // Tag items grid
677
- .tag-list,
678
- > div {
679
- display: flex;
680
- flex-direction: column;
681
- gap: $jv-space-2;
578
+ // Keep the header styled
579
+ h5 {
580
+ padding: $jv-space-3 0 !important;
581
+ border-bottom: none !important;
582
+ }
583
+ }
682
584
 
683
- > div,
684
- > a {
685
- display: flex;
686
- align-items: center;
687
- justify-content: space-between;
688
- padding: $jv-space-4 $jv-space-4;
689
- background: transparent;
690
- border: none;
691
- border-radius: $jv-radius-sm;
692
- color: $jv-text-main;
693
- font-size: 14px;
694
- font-weight: 500;
695
- text-decoration: none;
696
- transition: background-color $jv-transition-fast, color $jv-transition-fast; // Modern transitions
697
- cursor: pointer;
585
+ .popular-tags {
586
+ padding: 0 !important;
587
+ margin: 0;
588
+ }
698
589
 
699
- &:hover {
700
- background: rgba(0, 81, 255, 0.06);
701
- color: $jv-primary;
590
+ // Override Bootstrap's grid - make it a flowing wrap layout
591
+ .tag-list {
592
+ display: flex !important;
593
+ flex-wrap: wrap !important;
594
+ gap: $jv-space-2 !important; // 8px gap between pills
595
+ padding: 0 !important;
596
+ margin: 0 !important;
597
+
598
+ // Reset Bootstrap row/column styles
599
+ &.row {
600
+ margin: 0 !important;
601
+ display: flex !important;
602
+ flex-wrap: wrap !important;
603
+ }
604
+
605
+ // Reset column divs - let them be inline
606
+ > div {
607
+ flex: none !important;
608
+ width: auto !important;
609
+ padding: 0 !important;
610
+ margin: 0 !important;
611
+ max-width: none !important;
612
+ }
613
+
614
+ // Style each tag as a compact pill
615
+ .btn-ghost,
616
+ a.btn-ghost {
617
+ display: inline-flex !important;
618
+ flex-direction: row !important;
619
+ align-items: center !important;
620
+ gap: $jv-space-1 !important; // 4px between tag name and count
621
+ background: rgba(0, 0, 0, 0.04) !important;
622
+ border: 1px solid transparent !important;
623
+ border-radius: $jv-radius-pill !important;
624
+ // [Enhancement 5] Increased padding for better touch targets
625
+ padding: $jv-space-2 $jv-space-3 !important; // 8px vertical, 12px horizontal
626
+ transition: all $jv-transition-fast !important;
627
+ text-decoration: none !important;
628
+ width: auto !important;
629
+ min-height: auto !important;
630
+
631
+ &:hover {
632
+ background: $jv-primary-soft !important;
633
+ color: $jv-primary !important;
634
+ // [Enhancement 6] Subtle shadow on hover
635
+ box-shadow: $jv-shadow-xs !important;
636
+ transform: translateY(-1px);
637
+
638
+ .tag-item {
639
+ color: $jv-primary !important;
702
640
  }
703
641
 
704
- // Focus state for accessibility
705
- &:focus-visible {
706
- outline: none;
707
- box-shadow: $jv-focus-ring;
642
+ .tag-topic-count {
643
+ color: $jv-primary !important;
644
+ opacity: 0.7;
708
645
  }
646
+ }
647
+
648
+ &:focus-visible {
649
+ outline: none;
650
+ box-shadow: $jv-focus-ring;
651
+ }
652
+
653
+ .tag-item {
654
+ font-size: $jv-font-size-xs !important; // 12px
655
+ font-weight: 500 !important;
656
+ color: $jv-text-main !important;
657
+ line-height: 1.2 !important;
658
+ margin: 0 !important;
709
659
 
710
- // Topic count
711
- small,
712
- .count,
713
- span:last-child {
714
- font-size: 12px;
660
+ // [Enhancement 2] Add # icon before tag name
661
+ &::before {
662
+ content: "#";
715
663
  color: $jv-text-soft;
664
+ margin-right: 2px;
716
665
  font-weight: 400;
717
666
  }
718
667
  }
668
+
669
+ .tag-topic-count {
670
+ font-size: $jv-font-size-xs !important; // 12px
671
+ font-weight: 400 !important;
672
+ color: $jv-text-soft !important;
673
+ line-height: 1 !important;
674
+
675
+ // Show count in parentheses style
676
+ &::before {
677
+ content: "(";
678
+ }
679
+ &::after {
680
+ content: ")";
681
+ }
682
+ }
683
+
684
+ // [Enhancement 3] Color-code tags by popularity
685
+ // Tags with topics get slightly darker background
686
+ &[data-tag]:not([data-count="0"]) {
687
+ background: rgba(0, 0, 0, 0.06) !important;
688
+
689
+ .tag-item {
690
+ font-weight: 600 !important;
691
+ }
692
+ }
719
693
  }
720
694
  }
721
- }
722
695
 
723
- // ===========================================================
724
- // RECENT/TRENDING POSTS WIDGET (Sidebar)
725
- // ===========================================================
726
- div[data-widget-area="sidebar"] {
727
- #recent_posts,
728
- .recent-posts,
729
- ul {
730
- list-style: none;
731
- padding: 0;
732
- margin: 0;
696
+ // ===========================================================
697
+ // TRENDING POSTS WIDGET - Widget Essentials Specific
698
+ // ===========================================================
733
699
 
734
- li {
735
- padding: $jv-space-4 $jv-space-6;
736
- border-bottom: 1px solid $jv-border-subtle;
737
- transition: background-color $jv-transition-fast; // Modern transition
700
+ // Override Bootstrap's overflow-hidden on wrapper divs
701
+ .overflow-hidden {
702
+ overflow: visible !important;
703
+ }
738
704
 
739
- &:last-child {
740
- border-bottom: none;
741
- }
705
+ // The wrapper div after h5 (Trending Posts header) - make it scrollable
706
+ h5 + div {
707
+ max-height: 420px;
708
+ overflow-y: auto !important;
709
+ overflow-x: hidden !important;
742
710
 
711
+ // Scrollbar styling
712
+ &::-webkit-scrollbar {
713
+ width: 6px;
714
+ }
715
+ &::-webkit-scrollbar-track {
716
+ background: transparent;
717
+ }
718
+ &::-webkit-scrollbar-thumb {
719
+ background: rgba(0, 0, 0, 0.15);
720
+ border-radius: 3px;
743
721
  &:hover {
744
- background: $jv-hover-bg; // Consistent hover state
722
+ background: rgba(0, 0, 0, 0.25);
745
723
  }
724
+ }
725
+ }
746
726
 
747
- // Focus state for accessibility
748
- &:focus-within {
749
- outline: none;
750
- background: $jv-hover-bg;
751
- }
727
+ // Recent posts container - no scroll here, parent wrapper handles it
728
+ #recent_posts,
729
+ ul[id*="recent"] {
730
+ max-height: none !important;
731
+ overflow: visible !important;
732
+ padding: $jv-space-3 !important;
733
+ padding-bottom: $jv-space-5 !important;
734
+ margin: 0;
735
+ list-style: none;
736
+ display: flex !important;
737
+ flex-direction: column !important;
738
+ gap: $jv-space-3 !important;
739
+ }
752
740
 
753
- // Post header with avatar
754
- .d-flex {
755
- display: flex;
756
- align-items: center;
757
- gap: $jv-space-2;
758
- margin-bottom: $jv-space-2;
759
-
760
- // Avatar
761
- .avatar,
762
- img[class*="avatar"] {
763
- width: 20px !important;
764
- height: 20px !important;
765
- border-radius: 50%;
766
- flex-shrink: 0;
767
- }
741
+ // Style the actual widget-posts items
742
+ .widget-posts {
743
+ padding: $jv-space-3 $jv-space-4 !important;
744
+ transition: $jv-transition-shadow, border-color $jv-transition-fast !important;
745
+ border: 1px solid rgba(0,0,0,0.05) !important;
746
+ border-radius: $jv-radius-md !important;
747
+ background: $jv-surface !important;
748
+ cursor: pointer;
749
+ flex-shrink: 0 !important;
750
+ display: flex !important;
751
+ flex-direction: column !important;
752
+ gap: $jv-space-3 !important;
768
753
 
769
- // Username
770
- a:first-of-type {
771
- font-size: 12px;
772
- font-weight: 600;
773
- color: $jv-text-main;
774
- text-decoration: none;
754
+ &:hover {
755
+ border-color: $jv-border-strong !important;
756
+ box-shadow: $jv-shadow-sm;
757
+ }
775
758
 
776
- &:hover {
777
- color: $jv-primary;
778
- }
779
- }
759
+ &:focus-within {
760
+ outline: none;
761
+ box-shadow: $jv-shadow-md, $jv-focus-ring;
762
+ }
780
763
 
781
- // Timeago
782
- .timeago {
783
- font-size: 11px;
784
- color: $jv-text-soft;
785
- }
786
- }
764
+ // Hide hr elements
765
+ hr {
766
+ display: none !important;
767
+ }
787
768
 
788
- // Post title/content
789
- > a,
790
- .post-content a,
791
- p {
792
- display: block;
793
- font-size: 13px;
794
- font-weight: 500;
795
- color: $jv-text-main;
796
- text-decoration: none;
797
- line-height: 1.4;
798
- margin-bottom: $jv-space-2;
769
+ // Meta info row (author + timeago)
770
+ .d-flex.gap-2 {
771
+ display: flex !important;
772
+ align-items: center !important;
773
+ gap: $jv-space-2 !important;
774
+ font-size: $jv-font-size-xs;
775
+ color: $jv-text-muted;
776
+ flex-wrap: nowrap;
777
+ }
799
778
 
800
- // Line clamp
801
- display: -webkit-box;
802
- -webkit-line-clamp: 2;
803
- -webkit-box-orient: vertical;
804
- overflow: hidden;
779
+ .timeago {
780
+ font-size: $jv-font-size-xs;
781
+ color: $jv-text-soft;
782
+ }
805
783
 
806
- &:hover {
807
- color: $jv-primary;
808
- }
809
- }
784
+ .post-author a {
785
+ font-size: $jv-font-size-xs !important;
786
+ font-weight: 500 !important;
787
+ color: $jv-text-main !important;
788
+ }
810
789
 
811
- // Content preview text
812
- .post-content,
813
- .content,
814
- .text-xs {
815
- font-size: 12px;
816
- color: $jv-text-muted;
817
- line-height: 1.45;
818
- display: -webkit-box;
819
- -webkit-line-clamp: 2;
820
- -webkit-box-orient: vertical;
821
- overflow: hidden;
822
- }
790
+ // Title link
791
+ a {
792
+ font-size: 14px;
793
+ font-weight: 500;
794
+ color: $jv-text-main;
795
+ text-decoration: none;
796
+ line-height: $jv-line-height-tight;
823
797
 
824
- // Read more link
825
- a.stretched-link,
826
- .read-more {
827
- font-size: 12px;
828
- font-weight: 600;
798
+ &:hover {
829
799
  color: $jv-primary;
830
- text-decoration: none;
831
- margin-top: $jv-space-2;
832
- display: inline-block;
800
+ }
801
+ }
802
+
803
+ // Content preview
804
+ p,
805
+ .content,
806
+ .line-clamp-6 {
807
+ display: -webkit-box;
808
+ -webkit-line-clamp: 3;
809
+ -webkit-box-orient: vertical;
810
+ overflow: hidden;
811
+ font-size: $jv-font-size-sm !important;
812
+ color: $jv-text-muted !important;
813
+ line-height: $jv-line-height-base !important;
814
+ margin: 0;
815
+ }
816
+
817
+ // Read more link
818
+ a.stretched-link {
819
+ font-size: $jv-font-size-xs;
820
+ color: $jv-primary;
821
+ }
822
+
823
+ // Footer with "read more" link
824
+ .post-preview-footer {
825
+ margin-top: auto;
826
+
827
+ a {
828
+ font-size: $jv-font-size-xs !important;
829
+ font-weight: 600 !important;
830
+ color: $jv-primary !important;
831
+ text-decoration: none !important;
832
+ transition: color $jv-transition-fast !important;
833
+ display: inline-flex;
834
+ align-items: center;
835
+ gap: $jv-space-1;
833
836
 
834
837
  &:hover {
835
- text-decoration: underline;
838
+ color: $jv-primary-hover !important;
839
+ text-decoration: underline !important;
836
840
  }
837
- }
838
- }
839
- }
840
- }
841
841
 
842
- // ===========================================================
843
- // WIDGET HEADER ICONS
844
- // ===========================================================
845
- div[data-widget-area="sidebar"] {
846
- h5, h6, .widget-title {
847
- display: flex;
848
- align-items: center;
849
- gap: $jv-space-2;
842
+ &::after {
843
+ content: "→";
844
+ font-size: inherit;
845
+ transition: transform $jv-transition-fast;
846
+ }
850
847
 
851
- i {
852
- font-size: 14px;
853
- color: $jv-text-soft;
848
+ &:hover::after {
849
+ transform: translateX(2px);
850
+ }
851
+ }
854
852
  }
855
853
  }
856
854
  }
857
855
 
858
- // ===========================================================
859
- // EMPTY STATE
860
- // ===========================================================
861
- div[data-widget-area="sidebar"] {
862
- .empty,
863
- .no-content {
864
- padding: $jv-space-8;
865
- text-align: center;
866
- color: $jv-text-soft;
867
- font-size: $jv-font-size-sm;
868
- }
869
- }