create-feedbax 0.2.0 → 0.2.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.
Files changed (99) hide show
  1. package/dist/cli.js +2042 -16
  2. package/dist/index.js +1997 -5
  3. package/package.json +1 -1
  4. package/template/.feedbax-template.sha256 +1 -1
  5. package/template/AGENTS.md +13 -0
  6. package/template/CONNECTED.md +404 -0
  7. package/template/README.md +58 -0
  8. package/template/components.json +1 -1
  9. package/template/eslint.config.mjs +23 -0
  10. package/template/migrations/0001_connected.sql +6 -0
  11. package/template/migrations/0002_participation.sql +8 -0
  12. package/template/migrations/0003_images.sql +3 -0
  13. package/template/migrations/0004_followed_status.sql +9 -0
  14. package/template/package.json +9 -5
  15. package/template/src/authorized-draft-post.tsx +1 -0
  16. package/template/src/changelog-page.tsx +63 -54
  17. package/template/src/cloudflare-workers.d.ts +6 -0
  18. package/template/src/comment-creation.test.tsx +42 -1
  19. package/template/src/comment-thread-page.ts +11 -1
  20. package/template/src/components/command-palette.tsx +59 -30
  21. package/template/src/components/connected-identity-provider.tsx +108 -0
  22. package/template/src/components/device-profile-provider.tsx +41 -26
  23. package/template/src/components/follow-post-button.tsx +89 -0
  24. package/template/src/components/header.tsx +2 -0
  25. package/template/src/components/image-attachments.tsx +187 -0
  26. package/template/src/components/loader.tsx +48 -5
  27. package/template/src/components/notification-inbox.tsx +232 -0
  28. package/template/src/components/portal-footer.tsx +14 -0
  29. package/template/src/components/profile-menu.tsx +30 -0
  30. package/template/src/components/ui/components/command.tsx +30 -29
  31. package/template/src/components/ui/components/message-scroller.tsx +2 -2
  32. package/template/src/components/ui/components/scroll-area.tsx +0 -1
  33. package/template/src/components/ui/components/switch.tsx +29 -0
  34. package/template/src/components/ui/styles/globals.css +1 -1
  35. package/template/src/connected-identity.test.ts +144 -0
  36. package/template/src/connected-identity.ts +122 -0
  37. package/template/src/connected-participation.test.tsx +67 -0
  38. package/template/src/connected-runtime.test.ts +241 -0
  39. package/template/src/connected-runtime.ts +176 -0
  40. package/template/src/connected-social.test.tsx +158 -0
  41. package/template/src/feedback-cache-invalidation.ts +1 -0
  42. package/template/src/feedback-runtime.ts +79 -12
  43. package/template/src/feedbax/config/index.test.ts +28 -0
  44. package/template/src/feedbax/config/index.ts +93 -0
  45. package/template/src/feedbax/feedback/connected-feedback.ts +206 -0
  46. package/template/src/feedbax/feedback/connected.test.ts +272 -0
  47. package/template/src/feedbax/feedback/connected.ts +215 -0
  48. package/template/src/feedbax/feedback/email-delivery.test.ts +65 -0
  49. package/template/src/feedbax/feedback/email-delivery.ts +66 -0
  50. package/template/src/feedbax/feedback/identity-handoff.test.ts +81 -0
  51. package/template/src/feedbax/feedback/identity-handoff.ts +119 -0
  52. package/template/src/feedbax/feedback/image-feedback.ts +101 -0
  53. package/template/src/feedbax/feedback/images.test.ts +223 -0
  54. package/template/src/feedbax/feedback/images.ts +324 -0
  55. package/template/src/feedbax/feedback/index.ts +55 -1
  56. package/template/src/feedbax/feedback/notion-image-review.ts +55 -0
  57. package/template/src/feedbax/feedback/participation.test.ts +653 -0
  58. package/template/src/feedbax/feedback/participation.ts +502 -0
  59. package/template/src/images-runtime.test.ts +133 -0
  60. package/template/src/images-runtime.ts +125 -0
  61. package/template/src/index.css +97 -440
  62. package/template/src/lazy-post-detail-overlay.tsx +13 -2
  63. package/template/src/overlay-post-detail.test.tsx +59 -8
  64. package/template/src/overlay-post-detail.tsx +20 -69
  65. package/template/src/participation-client.ts +63 -0
  66. package/template/src/participation-runtime.test.ts +35 -0
  67. package/template/src/participation-runtime.ts +255 -0
  68. package/template/src/portal-comments.ts +24 -5
  69. package/template/src/portal-feedback-form.tsx +18 -3
  70. package/template/src/portal-feedback-runtime.ts +3 -0
  71. package/template/src/portal-feedback-server-function.ts +6 -3
  72. package/template/src/portal-feedback-submission.ts +10 -0
  73. package/template/src/portal-server-entry.ts +4 -0
  74. package/template/src/post-creation-flow.tsx +2 -2
  75. package/template/src/post-detail-content.test.tsx +233 -0
  76. package/template/src/post-detail-content.tsx +162 -0
  77. package/template/src/post-detail-query.ts +34 -0
  78. package/template/src/post-results.tsx +1 -1
  79. package/template/src/public-cache-policy.test.ts +11 -4
  80. package/template/src/public-cache-policy.ts +1 -1
  81. package/template/src/public-feedback-index.tsx +9 -39
  82. package/template/src/public-feedback-page.test.tsx +65 -0
  83. package/template/src/public-feedback-page.ts +12 -1
  84. package/template/src/public-post-detail-skeleton.tsx +54 -0
  85. package/template/src/public-post-detail.tsx +298 -208
  86. package/template/src/public-post-route.test.tsx +39 -3
  87. package/template/src/public-post-route.tsx +15 -28
  88. package/template/src/public-roadmap-route.test.tsx +38 -2
  89. package/template/src/public-roadmap-view.tsx +56 -23
  90. package/template/src/public-shell.test.tsx +26 -0
  91. package/template/src/routeTree.gen.ts +49 -3
  92. package/template/src/router.tsx +2 -0
  93. package/template/src/routes/__root.tsx +3 -5
  94. package/template/src/routes/email-preferences.tsx +77 -0
  95. package/template/src/routes/submit.tsx +1 -1
  96. package/template/src/safe-public-failure.ts +3 -1
  97. package/template/src/server.ts +41 -1
  98. package/template/src/trusted-feedback-handler.test.ts +1 -1
  99. package/template/src/vote-toggle.tsx +42 -9
@@ -1,4 +1,4 @@
1
- @import "@feedbax/ui/globals.css";
1
+ @import "./components/ui/styles/globals.css";
2
2
 
3
3
  :root {
4
4
  --portal-ink: var(--foreground);
@@ -154,13 +154,7 @@
154
154
 
155
155
  body {
156
156
  margin: 0;
157
- background:
158
- linear-gradient(
159
- color-mix(in srgb, var(--foreground) 3.5%, transparent) 1px,
160
- transparent 1px
161
- ),
162
- var(--portal-paper);
163
- background-size: 100% 4rem;
157
+ background: var(--portal-paper);
164
158
  color: var(--portal-ink);
165
159
  }
166
160
 
@@ -181,6 +175,14 @@ textarea:focus-visible {
181
175
  outline-offset: 3px;
182
176
  }
183
177
 
178
+ input[data-slot="command-input"]:focus-visible {
179
+ outline: none;
180
+ }
181
+
182
+ [data-slot="command-input-wrapper"]:focus-within {
183
+ box-shadow: inset 0 -1px 0 var(--ring);
184
+ }
185
+
184
186
  .vote-toggle-button {
185
187
  display: inline-flex;
186
188
  min-height: 2.5rem;
@@ -272,10 +274,10 @@ textarea:focus-visible {
272
274
 
273
275
  .feedback-submit-copy h2 {
274
276
  margin: 0;
275
- font-size: clamp(2rem, 4vw, 3.8rem);
276
- font-weight: 650;
277
- letter-spacing: -0.06em;
278
- line-height: 0.98;
277
+ font-size: var(--text-xl);
278
+ font-weight: 600;
279
+ letter-spacing: -0.025em;
280
+ line-height: 1.4;
279
281
  }
280
282
 
281
283
  .feedback-submit-copy > p:last-child {
@@ -466,8 +468,8 @@ textarea:focus-visible {
466
468
 
467
469
  .post-detail-dialog {
468
470
  display: block;
469
- width: min(70rem, calc(100vw - 2rem));
470
- max-width: 70rem;
471
+ width: min(64rem, calc(100vw - 2rem));
472
+ max-width: 64rem;
471
473
  max-height: calc(100svh - 2rem);
472
474
  overflow-y: auto;
473
475
  padding: 0;
@@ -483,32 +485,8 @@ textarea:focus-visible {
483
485
  min-height: 0;
484
486
  }
485
487
 
486
- .post-full-page-link {
487
- display: flex;
488
- min-height: 4.5rem;
489
- padding: 0 4.25rem 0 1.5rem;
490
- align-items: center;
491
- justify-content: flex-end;
492
- border-bottom: 1px solid var(--portal-rule);
493
- color: var(--muted-foreground);
494
- font-size: 0.8rem;
495
- font-weight: 600;
496
- text-decoration-color: transparent;
497
- text-underline-offset: 0.25rem;
498
- transition:
499
- color 160ms ease,
500
- text-decoration-color 160ms ease;
501
- }
502
-
503
- .post-full-page-link:hover {
504
- color: var(--portal-ink);
505
- text-decoration-color: currentColor;
506
- }
507
-
508
- .post-full-page-link svg {
509
- width: 0.9rem;
510
- height: 0.9rem;
511
- margin-left: 0.5rem;
488
+ .post-detail-dialog .post-detail-sidebar {
489
+ padding-top: 4rem;
512
490
  }
513
491
 
514
492
  .post-detail-drawer .overlay-post-detail {
@@ -534,9 +512,16 @@ textarea:focus-visible {
534
512
  }
535
513
 
536
514
  .portal-shell {
515
+ display: flex;
516
+ flex-direction: column;
537
517
  min-height: 100svh;
538
518
  }
539
519
 
520
+ #main-content {
521
+ flex: 1;
522
+ min-width: 0;
523
+ }
524
+
540
525
  .portal-header {
541
526
  display: flex;
542
527
  align-items: center;
@@ -624,7 +609,7 @@ textarea:focus-visible {
624
609
 
625
610
  .feedback-intro h1 {
626
611
  margin: 0;
627
- font-size: clamp(2rem, 4vw, 3.4rem);
612
+ font-size: var(--text-2xl);
628
613
  font-weight: 650;
629
614
  letter-spacing: -0.055em;
630
615
  line-height: 1;
@@ -638,331 +623,82 @@ textarea:focus-visible {
638
623
  line-height: 1.55;
639
624
  }
640
625
 
641
- .changelog-page {
642
- width: min(calc(100% - 2rem), 90rem);
643
- min-height: calc(100svh - 5rem);
644
- margin: 0 auto;
645
- padding: clamp(3rem, 7vw, 5rem) 0 6rem;
646
- animation: page-in 480ms ease-out both;
647
- }
648
-
649
- .changelog-heading {
650
- display: flex;
651
- align-items: flex-start;
652
- justify-content: space-between;
653
- gap: 2rem;
654
- }
655
-
656
- .changelog-heading h1 {
657
- margin: 0;
658
- font-size: clamp(1.75rem, 3vw, 2.25rem);
659
- font-weight: 650;
660
- letter-spacing: -0.04em;
661
- line-height: 1;
662
- }
663
-
664
- .changelog-heading p {
665
- margin: 0.75rem 0 0;
666
- color: var(--muted-foreground);
667
- font-size: 0.95rem;
668
- }
669
-
670
- .changelog-toolbar {
671
- display: flex;
672
- align-items: center;
673
- justify-content: space-between;
674
- gap: 1rem;
675
- margin: 2.5rem 0 1rem;
676
- }
677
-
678
- .changelog-filters {
679
- display: grid;
680
- grid-template-columns: repeat(4, minmax(0, 1fr));
681
- width: min(100%, 28rem);
682
- }
683
-
684
- .changelog-filters button {
685
- height: 2.5rem;
686
- padding-inline: 1rem;
687
- color: var(--muted-foreground);
688
- font-size: 0.8rem;
689
- }
690
-
691
- .changelog-filters button[aria-pressed="true"] {
692
- background: var(--muted);
693
- color: var(--foreground);
694
- }
695
-
696
626
  .changelog-timeline {
697
- position: relative;
698
627
  display: grid;
699
- gap: 0.75rem;
700
- margin: 0;
628
+ gap: 2.5rem;
629
+ max-width: 64rem;
630
+ margin: 2.5rem auto 0;
701
631
  padding: 0;
702
632
  list-style: none;
703
633
  }
704
634
 
705
- .changelog-timeline::before {
706
- position: absolute;
707
- top: 1.5rem;
708
- bottom: 4.5rem;
709
- left: 10.875rem;
710
- width: 1px;
711
- background: var(--border);
712
- content: "";
713
- }
714
-
715
635
  .changelog-timeline-entry {
716
636
  position: relative;
717
637
  display: grid;
718
- grid-template-columns: 9.75rem 1.5rem minmax(0, 1fr);
638
+ grid-template-columns: 8rem minmax(0, 1fr);
639
+ gap: 2rem;
719
640
  align-items: start;
720
641
  }
721
642
 
722
643
  .changelog-timeline-entry > time {
723
- padding-top: 1.1rem;
644
+ padding-top: 0.2rem;
724
645
  color: var(--muted-foreground);
725
- font-size: 0.8rem;
646
+ font-size: var(--text-xs);
726
647
  font-variant-numeric: tabular-nums;
727
648
  }
728
649
 
729
650
  .changelog-timeline-marker {
651
+ position: absolute;
730
652
  z-index: 1;
731
- width: 0.45rem;
732
- height: 0.45rem;
733
- margin: 1.35rem auto 0;
734
- border: 2px solid var(--background);
653
+ top: 0.45rem;
654
+ left: 10rem;
655
+ width: 0.4rem;
656
+ height: 0.4rem;
657
+ transform: translateX(-50%);
735
658
  border-radius: 50%;
736
- background: color-mix(
737
- in srgb,
738
- var(--muted-foreground) 55%,
739
- var(--background)
740
- );
741
- box-sizing: content-box;
659
+ background: var(--muted-foreground);
660
+ box-shadow: 0 0 0 4px var(--background);
742
661
  }
743
662
 
744
663
  .changelog-timeline-entry > article {
745
664
  min-width: 0;
665
+ padding: 0 0 2.5rem 2rem;
666
+ border-left: 1px solid var(--border);
667
+ border-bottom: 1px solid var(--border);
746
668
  scroll-margin-top: 6rem;
747
- border: 1px solid var(--border);
748
- background: color-mix(in srgb, var(--card) 36%, transparent);
749
- transition:
750
- border-color 180ms ease,
751
- background-color 180ms ease;
752
669
  }
753
670
 
754
- .changelog-timeline-entry > article:hover,
755
671
  .changelog-timeline-entry > article:target {
756
- border-color: color-mix(in srgb, var(--foreground) 28%, var(--border));
757
- background: color-mix(in srgb, var(--card) 72%, transparent);
758
- }
759
-
760
- .changelog-timeline-entry > article:target {
761
- outline: 1px solid color-mix(in srgb, var(--ring) 65%, transparent);
762
- outline-offset: 3px;
763
- }
764
-
765
- .changelog-entry-layout {
766
- padding: 1rem 1.5rem;
767
- }
768
-
769
- .changelog-entry-layout.has-image {
770
- display: grid;
771
- grid-template-columns: minmax(17rem, 1fr) minmax(20rem, 0.8fr);
772
- gap: clamp(1.5rem, 4vw, 4rem);
773
- align-items: center;
774
- min-height: 16rem;
775
- }
776
-
777
- .changelog-entry-copy {
778
- min-width: 0;
779
- }
780
-
781
- .changelog-labels {
782
- display: flex;
783
- flex-wrap: wrap;
784
- gap: 0.4rem;
785
- margin-bottom: 0.7rem;
786
- }
787
-
788
- .changelog-label {
789
- border-color: color-mix(in srgb, var(--foreground) 12%, transparent);
790
- background: color-mix(in srgb, var(--muted) 72%, transparent);
791
- color: var(--muted-foreground);
792
- }
793
-
794
- .changelog-label > span {
795
- width: 0.45rem;
796
- height: 0.45rem;
797
- border-radius: 50%;
798
- background: currentColor;
799
- }
800
-
801
- .changelog-label.is-new {
802
- background: color-mix(in srgb, var(--changelog-new) 12%, transparent);
803
- color: var(--changelog-new);
804
- }
805
-
806
- .changelog-label.is-improved {
807
- background: color-mix(in srgb, var(--changelog-improved) 12%, transparent);
808
- color: var(--changelog-improved);
809
- }
810
-
811
- .changelog-label.is-fixed {
812
- background: color-mix(in srgb, var(--destructive) 12%, transparent);
813
- color: var(--destructive);
814
- }
815
-
816
- .changelog-entry-title {
817
- display: flex;
818
- align-items: center;
819
- gap: 0.6rem;
820
- }
821
-
822
- .changelog-entry-title h2 {
823
- margin: 0;
824
- font-size: 1.1rem;
825
- font-weight: 650;
826
- letter-spacing: -0.025em;
827
- }
828
-
829
- .changelog-entry-title a {
830
- display: inline-grid;
831
- flex: none;
832
- width: 1.75rem;
833
- height: 1.75rem;
834
- place-items: center;
835
- color: var(--muted-foreground);
836
- opacity: 0.55;
837
- transition:
838
- color 160ms ease,
839
- opacity 160ms ease,
840
- transform 160ms ease;
841
- }
842
-
843
- .changelog-entry-title a:hover,
844
- .changelog-entry-title a:focus-visible {
845
- color: var(--foreground);
846
- opacity: 1;
847
- transform: translateY(-1px);
848
- }
849
-
850
- .changelog-entry-title svg {
851
- width: 0.9rem;
852
- height: 0.9rem;
853
- }
854
-
855
- .changelog-entry-summary {
856
- margin: 0.45rem 0 0;
857
- color: var(--muted-foreground);
858
- font-size: 0.9rem;
859
- line-height: 1.5;
672
+ outline: 1px solid var(--ring);
673
+ outline-offset: 0.75rem;
860
674
  }
861
675
 
862
676
  .changelog-entry-body {
863
- margin-top: 0.7rem;
677
+ display: grid;
678
+ gap: 1rem;
679
+ margin-top: 1rem;
864
680
  color: var(--muted-foreground);
865
- font-size: 0.86rem;
866
- line-height: 1.55;
681
+ font-size: var(--text-sm);
682
+ line-height: 1.75;
683
+ overflow-wrap: anywhere;
867
684
  }
868
685
 
869
- .changelog-entry-body p,
870
- .changelog-entry-body ul {
686
+ .changelog-entry-body p {
871
687
  margin: 0;
688
+ white-space: pre-line;
872
689
  }
873
690
 
874
- .changelog-entry-body ul {
875
- padding-left: 1.25rem;
876
- }
877
-
878
- .changelog-entry-layout img {
879
- display: block;
880
- width: 100%;
881
- border: 1px solid var(--border);
882
- background: var(--background);
883
- }
884
-
885
- .changelog-load-more {
886
- display: flex;
887
- justify-content: center;
888
- margin: 1rem 0 0 11.25rem;
889
- }
890
-
891
- @media (max-width: 800px) {
892
- .changelog-page {
893
- width: min(calc(100% - 2rem), 42rem);
894
- padding-top: 5rem;
895
- }
896
-
897
- .changelog-heading {
898
- align-items: stretch;
899
- flex-direction: column;
900
- }
901
-
902
- .changelog-heading button,
903
- .changelog-toolbar button {
904
- width: 100%;
905
- }
906
-
907
- .changelog-toolbar {
908
- display: grid;
909
- grid-template-columns: minmax(0, 1fr);
910
- margin-top: 1rem;
911
- }
912
-
913
- .changelog-filters {
914
- width: 100%;
915
- }
916
-
917
- .changelog-filters button {
918
- height: 2.75rem;
919
- min-width: 0;
920
- padding-inline: 0.45rem;
921
- font-size: 0.72rem;
922
- }
923
-
924
- .changelog-timeline::before {
925
- top: 3rem;
926
- bottom: 3rem;
927
- left: 0.35rem;
928
- }
929
-
691
+ @media (max-width: 640px) {
930
692
  .changelog-timeline-entry {
931
- grid-template-columns: 0.75rem minmax(0, 1fr);
932
- column-gap: 0.75rem;
933
- }
934
-
935
- .changelog-timeline-entry > time {
936
- grid-column: 2;
937
- padding: 0 0 0.55rem;
938
- }
939
-
940
- .changelog-timeline-marker {
941
- grid-column: 1;
942
- grid-row: 1 / span 2;
943
- margin-top: 0.25rem;
944
- }
945
-
946
- .changelog-timeline-entry > article {
947
- grid-column: 2;
948
- }
949
-
950
- .changelog-entry-layout,
951
- .changelog-entry-layout.has-image {
952
- display: grid;
953
693
  grid-template-columns: minmax(0, 1fr);
954
- gap: 1.25rem;
955
- min-height: 0;
956
- padding: 1.1rem;
694
+ gap: 0.75rem;
957
695
  }
958
-
959
- .changelog-load-more {
960
- margin-left: 1.5rem;
696
+ .changelog-timeline-entry > article {
697
+ padding-left: 0;
698
+ border-left: 0;
961
699
  }
962
-
963
- .changelog-load-more button {
964
- width: 100%;
965
- min-width: 0;
700
+ .changelog-timeline-marker {
701
+ display: none;
966
702
  }
967
703
  }
968
704
 
@@ -1041,76 +777,6 @@ textarea:focus-visible {
1041
777
  padding-top: 3rem;
1042
778
  }
1043
779
 
1044
- .feedback-feed-skeleton .animate-pulse,
1045
- .post-detail-skeleton .animate-pulse {
1046
- border-radius: 0;
1047
- }
1048
-
1049
- .feedback-skeleton-heading {
1050
- width: min(34rem, 80vw);
1051
- height: clamp(2.5rem, 7vw, 5.5rem);
1052
- }
1053
-
1054
- .feedback-skeleton-deck {
1055
- width: min(32rem, 70vw);
1056
- height: 1.25rem;
1057
- margin-top: 1.25rem;
1058
- }
1059
-
1060
- .feedback-skeleton-control {
1061
- width: 9rem;
1062
- height: 2.75rem;
1063
- }
1064
-
1065
- .feedback-skeleton-section-heading,
1066
- .feedback-skeleton-meta {
1067
- width: 8rem;
1068
- height: 0.75rem;
1069
- }
1070
-
1071
- .feedback-skeleton-row {
1072
- display: grid;
1073
- gap: 0.8rem;
1074
- padding: clamp(1.5rem, 3vw, 2.4rem) 0;
1075
- }
1076
-
1077
- .feedback-skeleton-title {
1078
- width: min(30rem, 70vw);
1079
- height: 2rem;
1080
- }
1081
-
1082
- .feedback-skeleton-copy {
1083
- width: min(42rem, 80vw);
1084
- height: 1rem;
1085
- }
1086
-
1087
- .post-detail-skeleton-back {
1088
- width: 8rem;
1089
- height: 1rem;
1090
- }
1091
-
1092
- .post-detail-skeleton-meta {
1093
- width: 12rem;
1094
- height: 0.8rem;
1095
- }
1096
-
1097
- .post-detail-skeleton-title {
1098
- width: min(44rem, 75vw);
1099
- height: clamp(3rem, 7vw, 6rem);
1100
- margin-top: 1.25rem;
1101
- }
1102
-
1103
- .post-detail-skeleton-copy {
1104
- width: min(52rem, 80vw);
1105
- height: 1rem;
1106
- margin-top: 2rem;
1107
- }
1108
-
1109
- .post-detail-skeleton-copy-short {
1110
- width: min(35rem, 60vw);
1111
- margin-top: 0.75rem;
1112
- }
1113
-
1114
780
  .creation-skeleton-eyebrow {
1115
781
  width: 7rem;
1116
782
  height: 0.75rem;
@@ -1275,7 +941,7 @@ textarea:focus-visible {
1275
941
  .roadmap-intro h1 {
1276
942
  max-width: 12ch;
1277
943
  margin: 0;
1278
- font-size: clamp(3rem, 7vw, 6.5rem);
944
+ font-size: var(--text-2xl);
1279
945
  font-weight: 650;
1280
946
  letter-spacing: -0.075em;
1281
947
  line-height: 0.94;
@@ -1468,7 +1134,7 @@ textarea:focus-visible {
1468
1134
  .feedback-detail h1 {
1469
1135
  max-width: 14ch;
1470
1136
  margin: 1.25rem 0 0;
1471
- font-size: clamp(3rem, 7vw, 6.5rem);
1137
+ font-size: var(--text-2xl);
1472
1138
  font-weight: 650;
1473
1139
  letter-spacing: -0.075em;
1474
1140
  line-height: 0.94;
@@ -1478,7 +1144,7 @@ textarea:focus-visible {
1478
1144
  max-width: 48rem;
1479
1145
  margin: clamp(2rem, 5vw, 4rem) 0 0;
1480
1146
  color: var(--muted-foreground);
1481
- font-size: clamp(1.15rem, 2vw, 1.5rem);
1147
+ font-size: var(--text-sm);
1482
1148
  line-height: 1.75;
1483
1149
  white-space: pre-wrap;
1484
1150
  }
@@ -1511,7 +1177,7 @@ textarea:focus-visible {
1511
1177
  }
1512
1178
 
1513
1179
  .public-post-detail {
1514
- width: min(90vw, 70rem);
1180
+ width: min(90vw, 64rem);
1515
1181
  padding: clamp(2rem, 5vw, 4rem) 0 5rem;
1516
1182
  }
1517
1183
 
@@ -1525,7 +1191,7 @@ textarea:focus-visible {
1525
1191
  .public-post-detail .post-detail-layout {
1526
1192
  display: grid;
1527
1193
  max-width: none;
1528
- grid-template-columns: minmax(0, 1fr) minmax(17rem, 0.42fr);
1194
+ grid-template-columns: minmax(0, 1fr) minmax(14rem, 0.38fr);
1529
1195
  margin-top: 1.5rem;
1530
1196
  border: 1px solid var(--portal-rule);
1531
1197
  background: color-mix(in srgb, var(--card) 55%, var(--background));
@@ -1539,7 +1205,7 @@ textarea:focus-visible {
1539
1205
  .post-detail-primary,
1540
1206
  .post-detail-sidebar {
1541
1207
  min-width: 0;
1542
- padding: clamp(1.5rem, 4vw, 2.5rem);
1208
+ padding: 1.5rem;
1543
1209
  }
1544
1210
 
1545
1211
  .post-detail-sidebar {
@@ -1578,19 +1244,24 @@ textarea:focus-visible {
1578
1244
  }
1579
1245
 
1580
1246
  .public-post-detail h1 {
1581
- max-width: 22ch;
1582
- margin: 1.5rem 0 0;
1583
- font-size: clamp(2rem, 4vw, 3rem);
1584
- font-weight: 650;
1585
- letter-spacing: -0.05em;
1586
- line-height: 1.05;
1247
+ max-width: none;
1248
+ margin: 1rem 0 0;
1249
+ font-size: var(--text-2xl);
1250
+ font-weight: 600;
1251
+ letter-spacing: -0.025em;
1252
+ line-height: 1.4;
1253
+ }
1254
+
1255
+ .public-post-detail[data-display="overlay"] h1 {
1256
+ font-size: var(--text-lg);
1257
+ line-height: 1.5;
1587
1258
  }
1588
1259
 
1589
1260
  .public-post-detail .feedback-detail-description {
1590
1261
  max-width: 45rem;
1591
1262
  margin: 0.75rem 0 0;
1592
1263
  color: var(--muted-foreground);
1593
- font-size: clamp(0.95rem, 1.4vw, 1.05rem);
1264
+ font-size: var(--text-sm);
1594
1265
  line-height: 1.65;
1595
1266
  }
1596
1267
 
@@ -1641,16 +1312,22 @@ textarea:focus-visible {
1641
1312
  letter-spacing: -0.02em;
1642
1313
  }
1643
1314
 
1644
- .post-detail-comments-empty {
1645
- min-height: 13rem;
1315
+ .post-detail-thread-list {
1316
+ max-height: 30rem;
1317
+ overflow-y: auto;
1318
+ overscroll-behavior: contain;
1319
+ scrollbar-gutter: stable;
1646
1320
  margin-top: 1.25rem;
1647
- border: 1px dashed var(--portal-rule);
1648
- background: color-mix(in srgb, var(--muted) 12%, transparent);
1321
+ border-top: 1px solid var(--portal-rule);
1649
1322
  }
1650
1323
 
1651
1324
  .comment-threads {
1652
- margin-top: 1.25rem;
1653
- border-block: 1px solid var(--portal-rule);
1325
+ padding-right: 0.5rem;
1326
+ }
1327
+
1328
+ .public-post-detail .comment-thread {
1329
+ max-width: none;
1330
+ margin-top: 0;
1654
1331
  }
1655
1332
 
1656
1333
  .comment-thread + .comment-thread {
@@ -1756,7 +1433,7 @@ textarea:focus-visible {
1756
1433
  }
1757
1434
 
1758
1435
  .comment-composer-input {
1759
- min-height: 7rem;
1436
+ min-height: 6rem;
1760
1437
  resize: vertical;
1761
1438
  border-color: color-mix(in srgb, var(--foreground) 28%, var(--portal-rule));
1762
1439
  background: var(--background);
@@ -1839,7 +1516,7 @@ textarea:focus-visible {
1839
1516
  .public-error h1 {
1840
1517
  max-width: 12ch;
1841
1518
  margin: 0;
1842
- font-size: clamp(3rem, 7vw, 6.5rem);
1519
+ font-size: var(--text-2xl);
1843
1520
  font-weight: 650;
1844
1521
  letter-spacing: -0.075em;
1845
1522
  line-height: 0.94;
@@ -1882,18 +1559,7 @@ textarea:focus-visible {
1882
1559
  }
1883
1560
 
1884
1561
  .portal-loading {
1885
- display: flex;
1886
- min-height: calc(100svh - 4.5rem);
1887
- align-items: center;
1888
- justify-content: center;
1889
- gap: 0.75rem;
1890
- color: var(--muted-foreground);
1891
- font-size: 0.85rem;
1892
- }
1893
-
1894
- .portal-loading svg {
1895
- width: 1.1rem;
1896
- animation: spin 900ms linear infinite;
1562
+ width: 100%;
1897
1563
  }
1898
1564
 
1899
1565
  @keyframes page-in {
@@ -2031,7 +1697,7 @@ textarea:focus-visible {
2031
1697
  }
2032
1698
 
2033
1699
  .feedback-detail h1 {
2034
- font-size: clamp(3rem, 15vw, 4.25rem);
1700
+ font-size: var(--text-2xl);
2035
1701
  }
2036
1702
 
2037
1703
  .feedback-detail-dates {
@@ -2040,7 +1706,7 @@ textarea:focus-visible {
2040
1706
  }
2041
1707
 
2042
1708
  .feedback-intro h1 {
2043
- font-size: clamp(2rem, 10vw, 3rem);
1709
+ font-size: var(--text-2xl);
2044
1710
  }
2045
1711
 
2046
1712
  .feedback-filters {
@@ -2085,7 +1751,7 @@ textarea:focus-visible {
2085
1751
  }
2086
1752
 
2087
1753
  .public-post-detail h1 {
2088
- font-size: clamp(1.85rem, 8vw, 2.5rem);
1754
+ font-size: var(--text-xl);
2089
1755
  }
2090
1756
 
2091
1757
  .post-detail-primary,
@@ -2101,10 +1767,6 @@ textarea:focus-visible {
2101
1767
  justify-content: flex-end;
2102
1768
  }
2103
1769
 
2104
- .post-detail-comments-empty {
2105
- min-height: 10rem;
2106
- }
2107
-
2108
1770
  .comment[data-reply="true"] {
2109
1771
  margin-left: 0.75rem;
2110
1772
  padding-left: 0.75rem;
@@ -2119,11 +1781,6 @@ textarea:focus-visible {
2119
1781
  .post-detail-details > div {
2120
1782
  grid-template-columns: minmax(5rem, 0.65fr) minmax(0, 1fr);
2121
1783
  }
2122
-
2123
- .post-full-page-link {
2124
- min-height: 3.75rem;
2125
- padding-right: 1.25rem;
2126
- }
2127
1784
  }
2128
1785
 
2129
1786
  @media (prefers-reduced-motion: reduce) {