From 42f1e2895ea0560b65a3b6d8e5019f27e5fda813 Mon Sep 17 00:00:00 2001 From: Malik Alleyne-Jones Date: Sat, 16 May 2026 22:00:24 -0400 Subject: [PATCH 1/2] feat: add nested (threaded) comments with a configurable max depth (#11) Adds threaded comment replies. - New nullable self-referencing `parent_id` column (additive migration); the Comment model gains parent()/replies() relations and a depth() helper. - HasComments::commentsQuery() returns only top-level comments when threading is enabled and eager-loads replies down to the configured max depth. - A "Reply" Filament action on each comment opens an inline reply editor; saveReply() persists the reply with its parent_id via SaveComment. The reply control is hidden once a comment reaches the max depth. - Replies render recursively beneath their parent with an indent. - Controlled by a `commentions.threading` config block (disabled by default, default max_depth 3). - Deleting a comment recursively deletes its replies (and their files). --- config/commentions.php | 16 ++ ..._id_to_commentions_comments_table.php.stub | 28 ++++ resources/dist/commentions.css | 2 +- resources/lang/ar/comments.php | 1 + resources/lang/en/comments.php | 1 + resources/lang/es/comments.php | 1 + resources/lang/fr/comments.php | 1 + resources/lang/nl/comments.php | 1 + resources/lang/ro/comments.php | 1 + resources/views/comment.blade.php | 46 +++++- src/Actions/SaveComment.php | 12 +- src/Comment.php | 38 +++++ src/CommentionsServiceProvider.php | 1 + src/HasComments.php | 32 +++- src/Livewire/Comment.php | 71 +++++++++ tests/Livewire/CommentThreadingTest.php | 145 ++++++++++++++++++ tests/TestCase.php | 1 + 17 files changed, 392 insertions(+), 6 deletions(-) create mode 100644 database/migrations/add_parent_id_to_commentions_comments_table.php.stub create mode 100644 tests/Livewire/CommentThreadingTest.php diff --git a/config/commentions.php b/config/commentions.php index 4267451..db4c6dd 100644 --- a/config/commentions.php +++ b/config/commentions.php @@ -46,6 +46,22 @@ 'allowed' => ['👍', '❤️', '😂', '😮', '😢', '🤔'], ], + /* + |-------------------------------------------------------------------------- + | Threading + |-------------------------------------------------------------------------- + | + | Nested (threaded) comment replies. Disabled by default. `max_depth` is + | the deepest reply level allowed — top-level comments are depth 0, so a + | max_depth of 3 permits replies down to depth 3. + | + */ + 'threading' => [ + 'enabled' => env('COMMENTIONS_THREADING_ENABLED', false), + + 'max_depth' => (int) env('COMMENTIONS_THREADING_MAX_DEPTH', 3), + ], + /* |-------------------------------------------------------------------------- | Subscriptions diff --git a/database/migrations/add_parent_id_to_commentions_comments_table.php.stub b/database/migrations/add_parent_id_to_commentions_comments_table.php.stub new file mode 100644 index 0000000..1ad9d25 --- /dev/null +++ b/database/migrations/add_parent_id_to_commentions_comments_table.php.stub @@ -0,0 +1,28 @@ +foreignId('parent_id') + ->nullable() + ->after('id') + ->constrained($table) + ->cascadeOnDelete(); + }); + } + + public function down(): void + { + Schema::table(config('commentions.tables.comments', 'comments'), function (Blueprint $blueprint) { + $blueprint->dropConstrainedForeignId('parent_id'); + }); + } +}; diff --git a/resources/dist/commentions.css b/resources/dist/commentions.css index 1807ccf..fb62790 100644 --- a/resources/dist/commentions.css +++ b/resources/dist/commentions.css @@ -1,2 +1,2 @@ /*! tailwindcss v4.0.6 | MIT License | https://tailwindcss.com */ -@layer theme{:root,:host{--comm-font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--comm-font-serif:ui-serif,Georgia,Cambria,"Times New Roman",Times,serif;--comm-font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--comm-color-red-50:oklch(.971 .013 17.38);--comm-color-red-100:oklch(.936 .032 17.717);--comm-color-red-200:oklch(.885 .062 18.334);--comm-color-red-300:oklch(.808 .114 19.571);--comm-color-red-400:oklch(.704 .191 22.216);--comm-color-red-500:oklch(.637 .237 25.331);--comm-color-red-600:oklch(.577 .245 27.325);--comm-color-red-700:oklch(.505 .213 27.518);--comm-color-red-800:oklch(.444 .177 26.899);--comm-color-red-900:oklch(.396 .141 25.723);--comm-color-red-950:oklch(.258 .092 26.042);--comm-color-orange-50:oklch(.98 .016 73.684);--comm-color-orange-100:oklch(.954 .038 75.164);--comm-color-orange-200:oklch(.901 .076 70.697);--comm-color-orange-300:oklch(.837 .128 66.29);--comm-color-orange-400:oklch(.75 .183 55.934);--comm-color-orange-500:oklch(.705 .213 47.604);--comm-color-orange-600:oklch(.646 .222 41.116);--comm-color-orange-700:oklch(.553 .195 38.402);--comm-color-orange-800:oklch(.47 .157 37.304);--comm-color-orange-900:oklch(.408 .123 38.172);--comm-color-orange-950:oklch(.266 .079 36.259);--comm-color-amber-50:oklch(.987 .022 95.277);--comm-color-amber-100:oklch(.962 .059 95.617);--comm-color-amber-200:oklch(.924 .12 95.746);--comm-color-amber-300:oklch(.879 .169 91.605);--comm-color-amber-400:oklch(.828 .189 84.429);--comm-color-amber-500:oklch(.769 .188 70.08);--comm-color-amber-600:oklch(.666 .179 58.318);--comm-color-amber-700:oklch(.555 .163 48.998);--comm-color-amber-800:oklch(.473 .137 46.201);--comm-color-amber-900:oklch(.414 .112 45.904);--comm-color-amber-950:oklch(.279 .077 45.635);--comm-color-yellow-50:oklch(.987 .026 102.212);--comm-color-yellow-100:oklch(.973 .071 103.193);--comm-color-yellow-200:oklch(.945 .129 101.54);--comm-color-yellow-300:oklch(.905 .182 98.111);--comm-color-yellow-400:oklch(.852 .199 91.936);--comm-color-yellow-500:oklch(.795 .184 86.047);--comm-color-yellow-600:oklch(.681 .162 75.834);--comm-color-yellow-700:oklch(.554 .135 66.442);--comm-color-yellow-800:oklch(.476 .114 61.907);--comm-color-yellow-900:oklch(.421 .095 57.708);--comm-color-yellow-950:oklch(.286 .066 53.813);--comm-color-lime-50:oklch(.986 .031 120.757);--comm-color-lime-100:oklch(.967 .067 122.328);--comm-color-lime-200:oklch(.938 .127 124.321);--comm-color-lime-300:oklch(.897 .196 126.665);--comm-color-lime-400:oklch(.841 .238 128.85);--comm-color-lime-500:oklch(.768 .233 130.85);--comm-color-lime-600:oklch(.648 .2 131.684);--comm-color-lime-700:oklch(.532 .157 131.589);--comm-color-lime-800:oklch(.453 .124 130.933);--comm-color-lime-900:oklch(.405 .101 131.063);--comm-color-lime-950:oklch(.274 .072 132.109);--comm-color-green-50:oklch(.982 .018 155.826);--comm-color-green-100:oklch(.962 .044 156.743);--comm-color-green-200:oklch(.925 .084 155.995);--comm-color-green-300:oklch(.871 .15 154.449);--comm-color-green-400:oklch(.792 .209 151.711);--comm-color-green-500:oklch(.723 .219 149.579);--comm-color-green-600:oklch(.627 .194 149.214);--comm-color-green-700:oklch(.527 .154 150.069);--comm-color-green-800:oklch(.448 .119 151.328);--comm-color-green-900:oklch(.393 .095 152.535);--comm-color-green-950:oklch(.266 .065 152.934);--comm-color-emerald-50:oklch(.979 .021 166.113);--comm-color-emerald-100:oklch(.95 .052 163.051);--comm-color-emerald-200:oklch(.905 .093 164.15);--comm-color-emerald-300:oklch(.845 .143 164.978);--comm-color-emerald-400:oklch(.765 .177 163.223);--comm-color-emerald-500:oklch(.696 .17 162.48);--comm-color-emerald-600:oklch(.596 .145 163.225);--comm-color-emerald-700:oklch(.508 .118 165.612);--comm-color-emerald-800:oklch(.432 .095 166.913);--comm-color-emerald-900:oklch(.378 .077 168.94);--comm-color-emerald-950:oklch(.262 .051 172.552);--comm-color-teal-50:oklch(.984 .014 180.72);--comm-color-teal-100:oklch(.953 .051 180.801);--comm-color-teal-200:oklch(.91 .096 180.426);--comm-color-teal-300:oklch(.855 .138 181.071);--comm-color-teal-400:oklch(.777 .152 181.912);--comm-color-teal-500:oklch(.704 .14 182.503);--comm-color-teal-600:oklch(.6 .118 184.704);--comm-color-teal-700:oklch(.511 .096 186.391);--comm-color-teal-800:oklch(.437 .078 188.216);--comm-color-teal-900:oklch(.386 .063 188.416);--comm-color-teal-950:oklch(.277 .046 192.524);--comm-color-cyan-50:oklch(.984 .019 200.873);--comm-color-cyan-100:oklch(.956 .045 203.388);--comm-color-cyan-200:oklch(.917 .08 205.041);--comm-color-cyan-300:oklch(.865 .127 207.078);--comm-color-cyan-400:oklch(.789 .154 211.53);--comm-color-cyan-500:oklch(.715 .143 215.221);--comm-color-cyan-600:oklch(.609 .126 221.723);--comm-color-cyan-700:oklch(.52 .105 223.128);--comm-color-cyan-800:oklch(.45 .085 224.283);--comm-color-cyan-900:oklch(.398 .07 227.392);--comm-color-cyan-950:oklch(.302 .056 229.695);--comm-color-sky-50:oklch(.977 .013 236.62);--comm-color-sky-100:oklch(.951 .026 236.824);--comm-color-sky-200:oklch(.901 .058 230.902);--comm-color-sky-300:oklch(.828 .111 230.318);--comm-color-sky-400:oklch(.746 .16 232.661);--comm-color-sky-500:oklch(.685 .169 237.323);--comm-color-sky-600:oklch(.588 .158 241.966);--comm-color-sky-700:oklch(.5 .134 242.749);--comm-color-sky-800:oklch(.443 .11 240.79);--comm-color-sky-900:oklch(.391 .09 240.876);--comm-color-sky-950:oklch(.293 .066 243.157);--comm-color-blue-50:oklch(.97 .014 254.604);--comm-color-blue-100:oklch(.932 .032 255.585);--comm-color-blue-200:oklch(.882 .059 254.128);--comm-color-blue-300:oklch(.809 .105 251.813);--comm-color-blue-400:oklch(.707 .165 254.624);--comm-color-blue-500:oklch(.623 .214 259.815);--comm-color-blue-600:oklch(.546 .245 262.881);--comm-color-blue-700:oklch(.488 .243 264.376);--comm-color-blue-800:oklch(.424 .199 265.638);--comm-color-blue-900:oklch(.379 .146 265.522);--comm-color-blue-950:oklch(.282 .091 267.935);--comm-color-indigo-50:oklch(.962 .018 272.314);--comm-color-indigo-100:oklch(.93 .034 272.788);--comm-color-indigo-200:oklch(.87 .065 274.039);--comm-color-indigo-300:oklch(.785 .115 274.713);--comm-color-indigo-400:oklch(.673 .182 276.935);--comm-color-indigo-500:oklch(.585 .233 277.117);--comm-color-indigo-600:oklch(.511 .262 276.966);--comm-color-indigo-700:oklch(.457 .24 277.023);--comm-color-indigo-800:oklch(.398 .195 277.366);--comm-color-indigo-900:oklch(.359 .144 278.697);--comm-color-indigo-950:oklch(.257 .09 281.288);--comm-color-violet-50:oklch(.969 .016 293.756);--comm-color-violet-100:oklch(.943 .029 294.588);--comm-color-violet-200:oklch(.894 .057 293.283);--comm-color-violet-300:oklch(.811 .111 293.571);--comm-color-violet-400:oklch(.702 .183 293.541);--comm-color-violet-500:oklch(.606 .25 292.717);--comm-color-violet-600:oklch(.541 .281 293.009);--comm-color-violet-700:oklch(.491 .27 292.581);--comm-color-violet-800:oklch(.432 .232 292.759);--comm-color-violet-900:oklch(.38 .189 293.745);--comm-color-violet-950:oklch(.283 .141 291.089);--comm-color-purple-50:oklch(.977 .014 308.299);--comm-color-purple-100:oklch(.946 .033 307.174);--comm-color-purple-200:oklch(.902 .063 306.703);--comm-color-purple-300:oklch(.827 .119 306.383);--comm-color-purple-400:oklch(.714 .203 305.504);--comm-color-purple-500:oklch(.627 .265 303.9);--comm-color-purple-600:oklch(.558 .288 302.321);--comm-color-purple-700:oklch(.496 .265 301.924);--comm-color-purple-800:oklch(.438 .218 303.724);--comm-color-purple-900:oklch(.381 .176 304.987);--comm-color-purple-950:oklch(.291 .149 302.717);--comm-color-fuchsia-50:oklch(.977 .017 320.058);--comm-color-fuchsia-100:oklch(.952 .037 318.852);--comm-color-fuchsia-200:oklch(.903 .076 319.62);--comm-color-fuchsia-300:oklch(.833 .145 321.434);--comm-color-fuchsia-400:oklch(.74 .238 322.16);--comm-color-fuchsia-500:oklch(.667 .295 322.15);--comm-color-fuchsia-600:oklch(.591 .293 322.896);--comm-color-fuchsia-700:oklch(.518 .253 323.949);--comm-color-fuchsia-800:oklch(.452 .211 324.591);--comm-color-fuchsia-900:oklch(.401 .17 325.612);--comm-color-fuchsia-950:oklch(.293 .136 325.661);--comm-color-pink-50:oklch(.971 .014 343.198);--comm-color-pink-100:oklch(.948 .028 342.258);--comm-color-pink-200:oklch(.899 .061 343.231);--comm-color-pink-300:oklch(.823 .12 346.018);--comm-color-pink-400:oklch(.718 .202 349.761);--comm-color-pink-500:oklch(.656 .241 354.308);--comm-color-pink-600:oklch(.592 .249 .584);--comm-color-pink-700:oklch(.525 .223 3.958);--comm-color-pink-800:oklch(.459 .187 3.815);--comm-color-pink-900:oklch(.408 .153 2.432);--comm-color-pink-950:oklch(.284 .109 3.907);--comm-color-rose-50:oklch(.969 .015 12.422);--comm-color-rose-100:oklch(.941 .03 12.58);--comm-color-rose-200:oklch(.892 .058 10.001);--comm-color-rose-300:oklch(.81 .117 11.638);--comm-color-rose-400:oklch(.712 .194 13.428);--comm-color-rose-500:oklch(.645 .246 16.439);--comm-color-rose-600:oklch(.586 .253 17.585);--comm-color-rose-700:oklch(.514 .222 16.935);--comm-color-rose-800:oklch(.455 .188 13.697);--comm-color-rose-900:oklch(.41 .159 10.272);--comm-color-rose-950:oklch(.271 .105 12.094);--comm-color-slate-50:oklch(.984 .003 247.858);--comm-color-slate-100:oklch(.968 .007 247.896);--comm-color-slate-200:oklch(.929 .013 255.508);--comm-color-slate-300:oklch(.869 .022 252.894);--comm-color-slate-400:oklch(.704 .04 256.788);--comm-color-slate-500:oklch(.554 .046 257.417);--comm-color-slate-600:oklch(.446 .043 257.281);--comm-color-slate-700:oklch(.372 .044 257.287);--comm-color-slate-800:oklch(.279 .041 260.031);--comm-color-slate-900:oklch(.208 .042 265.755);--comm-color-slate-950:oklch(.129 .042 264.695);--comm-color-gray-50:oklch(.985 .002 247.839);--comm-color-gray-100:oklch(.967 .003 264.542);--comm-color-gray-200:oklch(.928 .006 264.531);--comm-color-gray-300:oklch(.872 .01 258.338);--comm-color-gray-400:oklch(.707 .022 261.325);--comm-color-gray-500:oklch(.551 .027 264.364);--comm-color-gray-600:oklch(.446 .03 256.802);--comm-color-gray-700:oklch(.373 .034 259.733);--comm-color-gray-800:oklch(.278 .033 256.848);--comm-color-gray-900:oklch(.21 .034 264.665);--comm-color-gray-950:oklch(.13 .028 261.692);--comm-color-zinc-50:oklch(.985 0 0);--comm-color-zinc-100:oklch(.967 .001 286.375);--comm-color-zinc-200:oklch(.92 .004 286.32);--comm-color-zinc-300:oklch(.871 .006 286.286);--comm-color-zinc-400:oklch(.705 .015 286.067);--comm-color-zinc-500:oklch(.552 .016 285.938);--comm-color-zinc-600:oklch(.442 .017 285.786);--comm-color-zinc-700:oklch(.37 .013 285.805);--comm-color-zinc-800:oklch(.274 .006 286.033);--comm-color-zinc-900:oklch(.21 .006 285.885);--comm-color-zinc-950:oklch(.141 .005 285.823);--comm-color-neutral-50:oklch(.985 0 0);--comm-color-neutral-100:oklch(.97 0 0);--comm-color-neutral-200:oklch(.922 0 0);--comm-color-neutral-300:oklch(.87 0 0);--comm-color-neutral-400:oklch(.708 0 0);--comm-color-neutral-500:oklch(.556 0 0);--comm-color-neutral-600:oklch(.439 0 0);--comm-color-neutral-700:oklch(.371 0 0);--comm-color-neutral-800:oklch(.269 0 0);--comm-color-neutral-900:oklch(.205 0 0);--comm-color-neutral-950:oklch(.145 0 0);--comm-color-stone-50:oklch(.985 .001 106.423);--comm-color-stone-100:oklch(.97 .001 106.424);--comm-color-stone-200:oklch(.923 .003 48.717);--comm-color-stone-300:oklch(.869 .005 56.366);--comm-color-stone-400:oklch(.709 .01 56.259);--comm-color-stone-500:oklch(.553 .013 58.071);--comm-color-stone-600:oklch(.444 .011 73.639);--comm-color-stone-700:oklch(.374 .01 67.558);--comm-color-stone-800:oklch(.268 .007 34.298);--comm-color-stone-900:oklch(.216 .006 56.043);--comm-color-stone-950:oklch(.147 .004 49.25);--comm-color-black:#000;--comm-color-white:#fff;--comm-spacing:.25rem;--comm-breakpoint-sm:40rem;--comm-breakpoint-md:48rem;--comm-breakpoint-lg:64rem;--comm-breakpoint-xl:80rem;--comm-breakpoint-2xl:96rem;--comm-container-3xs:16rem;--comm-container-2xs:18rem;--comm-container-xs:20rem;--comm-container-sm:24rem;--comm-container-md:28rem;--comm-container-lg:32rem;--comm-container-xl:36rem;--comm-container-2xl:42rem;--comm-container-3xl:48rem;--comm-container-4xl:56rem;--comm-container-5xl:64rem;--comm-container-6xl:72rem;--comm-container-7xl:80rem;--comm-text-xs:.75rem;--comm-text-xs--line-height:calc(1/.75);--comm-text-sm:.875rem;--comm-text-sm--line-height:calc(1.25/.875);--comm-text-base:1rem;--comm-text-base--line-height:calc(1.5/1);--comm-text-lg:1.125rem;--comm-text-lg--line-height:calc(1.75/1.125);--comm-text-xl:1.25rem;--comm-text-xl--line-height:calc(1.75/1.25);--comm-text-2xl:1.5rem;--comm-text-2xl--line-height:calc(2/1.5);--comm-text-3xl:1.875rem;--comm-text-3xl--line-height:calc(2.25/1.875);--comm-text-4xl:2.25rem;--comm-text-4xl--line-height:calc(2.5/2.25);--comm-text-5xl:3rem;--comm-text-5xl--line-height:1;--comm-text-6xl:3.75rem;--comm-text-6xl--line-height:1;--comm-text-7xl:4.5rem;--comm-text-7xl--line-height:1;--comm-text-8xl:6rem;--comm-text-8xl--line-height:1;--comm-text-9xl:8rem;--comm-text-9xl--line-height:1;--comm-font-weight-thin:100;--comm-font-weight-extralight:200;--comm-font-weight-light:300;--comm-font-weight-normal:400;--comm-font-weight-medium:500;--comm-font-weight-semibold:600;--comm-font-weight-bold:700;--comm-font-weight-extrabold:800;--comm-font-weight-black:900;--comm-tracking-tighter:-.05em;--comm-tracking-tight:-.025em;--comm-tracking-normal:0em;--comm-tracking-wide:.025em;--comm-tracking-wider:.05em;--comm-tracking-widest:.1em;--comm-leading-tight:1.25;--comm-leading-snug:1.375;--comm-leading-normal:1.5;--comm-leading-relaxed:1.625;--comm-leading-loose:2;--comm-radius-xs:.125rem;--comm-radius-sm:.25rem;--comm-radius-md:.375rem;--comm-radius-lg:.5rem;--comm-radius-xl:.75rem;--comm-radius-2xl:1rem;--comm-radius-3xl:1.5rem;--comm-radius-4xl:2rem;--comm-shadow-2xs:0 1px #0000000d;--comm-shadow-xs:0 1px 2px 0 #0000000d;--comm-shadow-sm:0 1px 3px 0 #0000001a,0 1px 2px -1px #0000001a;--comm-shadow-md:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a;--comm-shadow-lg:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;--comm-shadow-xl:0 20px 25px -5px #0000001a,0 8px 10px -6px #0000001a;--comm-shadow-2xl:0 25px 50px -12px #00000040;--comm-inset-shadow-2xs:inset 0 1px #0000000d;--comm-inset-shadow-xs:inset 0 1px 1px #0000000d;--comm-inset-shadow-sm:inset 0 2px 4px #0000000d;--comm-drop-shadow-xs:0 1px 1px #0000000d;--comm-drop-shadow-sm:0 1px 2px #00000026;--comm-drop-shadow-md:0 3px 3px #0000001f;--comm-drop-shadow-lg:0 4px 4px #00000026;--comm-drop-shadow-xl:0 9px 7px #0000001a;--comm-drop-shadow-2xl:0 25px 25px #00000026;--comm-ease-in:cubic-bezier(.4,0,1,1);--comm-ease-out:cubic-bezier(0,0,.2,1);--comm-ease-in-out:cubic-bezier(.4,0,.2,1);--comm-animate-spin:spin 1s linear infinite;--comm-animate-ping:ping 1s cubic-bezier(0,0,.2,1)infinite;--comm-animate-pulse:pulse 2s cubic-bezier(.4,0,.6,1)infinite;--comm-animate-bounce:bounce 1s infinite;--comm-blur-xs:4px;--comm-blur-sm:8px;--comm-blur-md:12px;--comm-blur-lg:16px;--comm-blur-xl:24px;--comm-blur-2xl:40px;--comm-blur-3xl:64px;--comm-perspective-dramatic:100px;--comm-perspective-near:300px;--comm-perspective-normal:500px;--comm-perspective-midrange:800px;--comm-perspective-distant:1200px;--comm-aspect-video:16/9;--comm-default-transition-duration:.15s;--comm-default-transition-timing-function:cubic-bezier(.4,0,.2,1);--comm-default-font-family:var(--font-sans);--comm-default-font-feature-settings:var(--font-sans--font-feature-settings);--comm-default-font-variation-settings:var(--font-sans--font-variation-settings);--comm-default-mono-font-family:var(--font-mono);--comm-default-mono-font-feature-settings:var(--font-mono--font-feature-settings);--comm-default-mono-font-variation-settings:var(--font-mono--font-variation-settings)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}body{line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1;color:color-mix(in oklab,currentColor 50%,transparent)}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.comm\:absolute{position:absolute!important}.comm\:relative{position:relative!important}.comm\:sticky{position:sticky!important}.comm\:top-4{top:calc(var(--comm-spacing)*4)!important}.comm\:bottom-full{bottom:100%!important}.comm\:z-10{z-index:10!important}.comm\:mt-0\.5{margin-top:calc(var(--comm-spacing)*.5)!important}.comm\:mt-1{margin-top:calc(var(--comm-spacing)*1)!important}.comm\:mt-2{margin-top:calc(var(--comm-spacing)*2)!important}.comm\:mb-2{margin-bottom:calc(var(--comm-spacing)*2)!important}.comm\:mb-3{margin-bottom:calc(var(--comm-spacing)*3)!important}.comm\:ml-1{margin-left:calc(var(--comm-spacing)*1)!important}.comm\:ml-2{margin-left:calc(var(--comm-spacing)*2)!important}.comm\:flex{display:flex!important}.comm\:hidden{display:none!important}.comm\:inline-block{display:inline-block!important}.comm\:inline-flex{display:inline-flex!important}.comm\:h-3{height:calc(var(--comm-spacing)*3)!important}.comm\:h-4{height:calc(var(--comm-spacing)*4)!important}.comm\:h-8{height:calc(var(--comm-spacing)*8)!important}.comm\:h-10{height:calc(var(--comm-spacing)*10)!important}.comm\:h-full{height:100%!important}.comm\:w-3{width:calc(var(--comm-spacing)*3)!important}.comm\:w-4{width:calc(var(--comm-spacing)*4)!important}.comm\:w-8{width:calc(var(--comm-spacing)*8)!important}.comm\:w-10{width:calc(var(--comm-spacing)*10)!important}.comm\:w-48{width:calc(var(--comm-spacing)*48)!important}.comm\:w-full{width:100%!important}.comm\:w-max{width:max-content!important}.comm\:max-w-xs{max-width:var(--comm-container-xs)!important}.comm\:min-w-full{min-width:100%!important}.comm\:flex-1{flex:1!important}.comm\:flex-shrink-0{flex-shrink:0!important}.comm\:flex-col{flex-direction:column!important}.comm\:flex-wrap{flex-wrap:wrap!important}.comm\:items-center{align-items:center!important}.comm\:items-start{align-items:flex-start!important}.comm\:justify-between{justify-content:space-between!important}.comm\:justify-center{justify-content:center!important}.comm\:justify-end{justify-content:flex-end!important}.comm\:gap-1{gap:calc(var(--comm-spacing)*1)!important}.comm\:gap-2{gap:calc(var(--comm-spacing)*2)!important}.comm\:gap-4{gap:calc(var(--comm-spacing)*4)!important}.comm\:gap-x-1{column-gap:calc(var(--comm-spacing)*1)!important}.comm\:gap-x-2{column-gap:calc(var(--comm-spacing)*2)!important}.comm\:gap-x-4{column-gap:calc(var(--comm-spacing)*4)!important}:where(.comm\:space-y-1>:not(:last-child)){--tw-space-y-reverse:0!important;margin-block-start:calc(calc(var(--comm-spacing)*1)*var(--tw-space-y-reverse))!important;margin-block-end:calc(calc(var(--comm-spacing)*1)*calc(1 - var(--tw-space-y-reverse)))!important}:where(.comm\:space-y-2>:not(:last-child)){--tw-space-y-reverse:0!important;margin-block-start:calc(calc(var(--comm-spacing)*2)*var(--tw-space-y-reverse))!important;margin-block-end:calc(calc(var(--comm-spacing)*2)*calc(1 - var(--tw-space-y-reverse)))!important}:where(.comm\:space-y-6>:not(:last-child)){--tw-space-y-reverse:0!important;margin-block-start:calc(calc(var(--comm-spacing)*6)*var(--tw-space-y-reverse))!important;margin-block-end:calc(calc(var(--comm-spacing)*6)*calc(1 - var(--tw-space-y-reverse)))!important}.comm\:gap-y-2{row-gap:calc(var(--comm-spacing)*2)!important}.comm\:truncate{text-overflow:ellipsis!important;white-space:nowrap!important;overflow:hidden!important}.comm\:rounded-full{border-radius:3.40282e38px!important}.comm\:rounded-lg{border-radius:var(--comm-radius-lg)!important}.comm\:rounded-md{border-radius:var(--comm-radius-md)!important}.comm\:border{border-style:var(--tw-border-style)!important;border-width:1px!important}.comm\:border-t{border-top-style:var(--tw-border-style)!important;border-top-width:1px!important}.comm\:border-dashed{--tw-border-style:dashed!important;border-style:dashed!important}.comm\:border-gray-200{border-color:var(--comm-color-gray-200)!important}.comm\:border-gray-300{border-color:var(--comm-color-gray-300)!important}.comm\:bg-blue-100{background-color:var(--comm-color-blue-100)!important}.comm\:bg-gray-50{background-color:var(--comm-color-gray-50)!important}.comm\:bg-gray-100{background-color:var(--comm-color-gray-100)!important}.comm\:bg-gray-300{background-color:var(--comm-color-gray-300)!important}.comm\:bg-white{background-color:var(--comm-color-white)!important}.comm\:object-cover{object-fit:cover!important}.comm\:object-center{object-position:center!important}.comm\:p-1{padding:calc(var(--comm-spacing)*1)!important}.comm\:p-2{padding:calc(var(--comm-spacing)*2)!important}.comm\:p-4{padding:calc(var(--comm-spacing)*4)!important}.comm\:p-6{padding:calc(var(--comm-spacing)*6)!important}.comm\:px-1\.5{padding-inline:calc(var(--comm-spacing)*1.5)!important}.comm\:px-2{padding-inline:calc(var(--comm-spacing)*2)!important}.comm\:py-0\.5{padding-block:calc(var(--comm-spacing)*.5)!important}.comm\:py-4{padding-block:calc(var(--comm-spacing)*4)!important}.comm\:pt-2{padding-top:calc(var(--comm-spacing)*2)!important}.comm\:pt-3{padding-top:calc(var(--comm-spacing)*3)!important}.comm\:pl-2{padding-left:calc(var(--comm-spacing)*2)!important}.comm\:pl-6{padding-left:calc(var(--comm-spacing)*6)!important}.comm\:text-center{text-align:center!important}.comm\:text-sm{font-size:var(--comm-text-sm)!important;line-height:var(--tw-leading,var(--comm-text-sm--line-height))!important}.comm\:text-xs{font-size:var(--comm-text-xs)!important;line-height:var(--tw-leading,var(--comm-text-xs--line-height))!important}.comm\:font-bold{--tw-font-weight:var(--comm-font-weight-bold)!important;font-weight:var(--comm-font-weight-bold)!important}.comm\:font-medium{--tw-font-weight:var(--comm-font-weight-medium)!important;font-weight:var(--comm-font-weight-medium)!important}.comm\:whitespace-nowrap{white-space:nowrap!important}.comm\:text-gray-300{color:var(--comm-color-gray-300)!important}.comm\:text-gray-400{color:var(--comm-color-gray-400)!important}.comm\:text-gray-500{color:var(--comm-color-gray-500)!important}.comm\:text-gray-600{color:var(--comm-color-gray-600)!important}.comm\:text-gray-700{color:var(--comm-color-gray-700)!important}.comm\:text-gray-800{color:var(--comm-color-gray-800)!important}.comm\:text-gray-900{color:var(--comm-color-gray-900)!important}.comm\:shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a)!important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important}.comm\:shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a)!important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important}.comm\:transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter!important;transition-timing-function:var(--tw-ease,var(--comm-default-transition-timing-function))!important;transition-duration:var(--tw-duration,var(--comm-default-transition-duration))!important}@media (hover:hover){.comm\:hover\:bg-gray-100:hover{background-color:var(--comm-color-gray-100)!important}.comm\:hover\:bg-gray-200:hover{background-color:var(--comm-color-gray-200)!important}}.comm\:focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentColor)!important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important}.comm\:focus\:ring-offset-2:focus{--tw-ring-offset-width:2px!important;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)!important}.comm\:focus\:outline-none:focus{--tw-outline-style:none!important;outline-style:none!important}.comm\:disabled\:cursor-not-allowed:disabled{cursor:not-allowed!important}.comm\:disabled\:opacity-50:disabled{opacity:.5!important}.comm\:dark\:border-gray-600:where(.dark,.dark *){border-color:var(--comm-color-gray-600)!important}.comm\:dark\:border-gray-700:where(.dark,.dark *){border-color:var(--comm-color-gray-700)!important}.comm\:dark\:bg-gray-600:where(.dark,.dark *){background-color:var(--comm-color-gray-600)!important}.comm\:dark\:bg-gray-800:where(.dark,.dark *){background-color:var(--comm-color-gray-800)!important}.comm\:dark\:bg-gray-900:where(.dark,.dark *){background-color:var(--comm-color-gray-900)!important}.comm\:dark\:text-gray-100:where(.dark,.dark *){color:var(--comm-color-gray-100)!important}.comm\:dark\:text-gray-200:where(.dark,.dark *){color:var(--comm-color-gray-200)!important}.comm\:dark\:text-gray-300:where(.dark,.dark *){color:var(--comm-color-gray-300)!important}.comm\:dark\:text-gray-400:where(.dark,.dark *){color:var(--comm-color-gray-400)!important}.comm\:dark\:text-gray-500:where(.dark,.dark *){color:var(--comm-color-gray-500)!important}@media (hover:hover){.comm\:dark\:hover\:bg-gray-600:where(.dark,.dark *):hover{background-color:var(--comm-color-gray-600)!important}.comm\:dark\:hover\:bg-gray-700:where(.dark,.dark *):hover{background-color:var(--comm-color-gray-700)!important}}}[x-cloak]{display:none}.tiptap{font-size:var(--comm-text-sm)!important;line-height:var(--tw-leading,var(--comm-text-sm--line-height))!important;--tw-leading:var(--comm-leading-normal)!important;line-height:var(--comm-leading-normal)!important}.tiptap p.is-editor-empty:before{color:#adb5bd;content:attr(data-placeholder);float:inline-start;pointer-events:none;height:0}.tiptap .mention{background-color:var(--comm-color-gray-200)!important;padding-inline:calc(var(--comm-spacing)*1)!important;padding-block:calc(var(--comm-spacing)*.5)!important;--tw-font-weight:var(--comm-font-weight-bold)!important;font-weight:var(--comm-font-weight-bold)!important;color:var(--comm-color-blue-500)!important;border-radius:.25rem!important;display:inline-block!important}.mention-suggestion{z-index:1000;background:#fff;border:1px solid #ddd;border-radius:5px;max-height:150px;padding:5px;overflow-y:auto}.mention-item{cursor:pointer;padding:5px 10px}.mention-item:hover{background-color:var(--comm-color-gray-100)!important}@keyframes spin{to{transform:rotate(360deg)}}@keyframes ping{75%,to{opacity:0;transform:scale(2)}}@keyframes pulse{50%{opacity:.5}}@keyframes bounce{0%,to{animation-timing-function:cubic-bezier(.8,0,1,1);transform:translateY(-25%)}50%{animation-timing-function:cubic-bezier(0,0,.2,1);transform:none}}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-leading{syntax:"*";inherits:false} \ No newline at end of file +@layer theme{:root,:host{--comm-font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--comm-font-serif:ui-serif,Georgia,Cambria,"Times New Roman",Times,serif;--comm-font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--comm-color-red-50:oklch(.971 .013 17.38);--comm-color-red-100:oklch(.936 .032 17.717);--comm-color-red-200:oklch(.885 .062 18.334);--comm-color-red-300:oklch(.808 .114 19.571);--comm-color-red-400:oklch(.704 .191 22.216);--comm-color-red-500:oklch(.637 .237 25.331);--comm-color-red-600:oklch(.577 .245 27.325);--comm-color-red-700:oklch(.505 .213 27.518);--comm-color-red-800:oklch(.444 .177 26.899);--comm-color-red-900:oklch(.396 .141 25.723);--comm-color-red-950:oklch(.258 .092 26.042);--comm-color-orange-50:oklch(.98 .016 73.684);--comm-color-orange-100:oklch(.954 .038 75.164);--comm-color-orange-200:oklch(.901 .076 70.697);--comm-color-orange-300:oklch(.837 .128 66.29);--comm-color-orange-400:oklch(.75 .183 55.934);--comm-color-orange-500:oklch(.705 .213 47.604);--comm-color-orange-600:oklch(.646 .222 41.116);--comm-color-orange-700:oklch(.553 .195 38.402);--comm-color-orange-800:oklch(.47 .157 37.304);--comm-color-orange-900:oklch(.408 .123 38.172);--comm-color-orange-950:oklch(.266 .079 36.259);--comm-color-amber-50:oklch(.987 .022 95.277);--comm-color-amber-100:oklch(.962 .059 95.617);--comm-color-amber-200:oklch(.924 .12 95.746);--comm-color-amber-300:oklch(.879 .169 91.605);--comm-color-amber-400:oklch(.828 .189 84.429);--comm-color-amber-500:oklch(.769 .188 70.08);--comm-color-amber-600:oklch(.666 .179 58.318);--comm-color-amber-700:oklch(.555 .163 48.998);--comm-color-amber-800:oklch(.473 .137 46.201);--comm-color-amber-900:oklch(.414 .112 45.904);--comm-color-amber-950:oklch(.279 .077 45.635);--comm-color-yellow-50:oklch(.987 .026 102.212);--comm-color-yellow-100:oklch(.973 .071 103.193);--comm-color-yellow-200:oklch(.945 .129 101.54);--comm-color-yellow-300:oklch(.905 .182 98.111);--comm-color-yellow-400:oklch(.852 .199 91.936);--comm-color-yellow-500:oklch(.795 .184 86.047);--comm-color-yellow-600:oklch(.681 .162 75.834);--comm-color-yellow-700:oklch(.554 .135 66.442);--comm-color-yellow-800:oklch(.476 .114 61.907);--comm-color-yellow-900:oklch(.421 .095 57.708);--comm-color-yellow-950:oklch(.286 .066 53.813);--comm-color-lime-50:oklch(.986 .031 120.757);--comm-color-lime-100:oklch(.967 .067 122.328);--comm-color-lime-200:oklch(.938 .127 124.321);--comm-color-lime-300:oklch(.897 .196 126.665);--comm-color-lime-400:oklch(.841 .238 128.85);--comm-color-lime-500:oklch(.768 .233 130.85);--comm-color-lime-600:oklch(.648 .2 131.684);--comm-color-lime-700:oklch(.532 .157 131.589);--comm-color-lime-800:oklch(.453 .124 130.933);--comm-color-lime-900:oklch(.405 .101 131.063);--comm-color-lime-950:oklch(.274 .072 132.109);--comm-color-green-50:oklch(.982 .018 155.826);--comm-color-green-100:oklch(.962 .044 156.743);--comm-color-green-200:oklch(.925 .084 155.995);--comm-color-green-300:oklch(.871 .15 154.449);--comm-color-green-400:oklch(.792 .209 151.711);--comm-color-green-500:oklch(.723 .219 149.579);--comm-color-green-600:oklch(.627 .194 149.214);--comm-color-green-700:oklch(.527 .154 150.069);--comm-color-green-800:oklch(.448 .119 151.328);--comm-color-green-900:oklch(.393 .095 152.535);--comm-color-green-950:oklch(.266 .065 152.934);--comm-color-emerald-50:oklch(.979 .021 166.113);--comm-color-emerald-100:oklch(.95 .052 163.051);--comm-color-emerald-200:oklch(.905 .093 164.15);--comm-color-emerald-300:oklch(.845 .143 164.978);--comm-color-emerald-400:oklch(.765 .177 163.223);--comm-color-emerald-500:oklch(.696 .17 162.48);--comm-color-emerald-600:oklch(.596 .145 163.225);--comm-color-emerald-700:oklch(.508 .118 165.612);--comm-color-emerald-800:oklch(.432 .095 166.913);--comm-color-emerald-900:oklch(.378 .077 168.94);--comm-color-emerald-950:oklch(.262 .051 172.552);--comm-color-teal-50:oklch(.984 .014 180.72);--comm-color-teal-100:oklch(.953 .051 180.801);--comm-color-teal-200:oklch(.91 .096 180.426);--comm-color-teal-300:oklch(.855 .138 181.071);--comm-color-teal-400:oklch(.777 .152 181.912);--comm-color-teal-500:oklch(.704 .14 182.503);--comm-color-teal-600:oklch(.6 .118 184.704);--comm-color-teal-700:oklch(.511 .096 186.391);--comm-color-teal-800:oklch(.437 .078 188.216);--comm-color-teal-900:oklch(.386 .063 188.416);--comm-color-teal-950:oklch(.277 .046 192.524);--comm-color-cyan-50:oklch(.984 .019 200.873);--comm-color-cyan-100:oklch(.956 .045 203.388);--comm-color-cyan-200:oklch(.917 .08 205.041);--comm-color-cyan-300:oklch(.865 .127 207.078);--comm-color-cyan-400:oklch(.789 .154 211.53);--comm-color-cyan-500:oklch(.715 .143 215.221);--comm-color-cyan-600:oklch(.609 .126 221.723);--comm-color-cyan-700:oklch(.52 .105 223.128);--comm-color-cyan-800:oklch(.45 .085 224.283);--comm-color-cyan-900:oklch(.398 .07 227.392);--comm-color-cyan-950:oklch(.302 .056 229.695);--comm-color-sky-50:oklch(.977 .013 236.62);--comm-color-sky-100:oklch(.951 .026 236.824);--comm-color-sky-200:oklch(.901 .058 230.902);--comm-color-sky-300:oklch(.828 .111 230.318);--comm-color-sky-400:oklch(.746 .16 232.661);--comm-color-sky-500:oklch(.685 .169 237.323);--comm-color-sky-600:oklch(.588 .158 241.966);--comm-color-sky-700:oklch(.5 .134 242.749);--comm-color-sky-800:oklch(.443 .11 240.79);--comm-color-sky-900:oklch(.391 .09 240.876);--comm-color-sky-950:oklch(.293 .066 243.157);--comm-color-blue-50:oklch(.97 .014 254.604);--comm-color-blue-100:oklch(.932 .032 255.585);--comm-color-blue-200:oklch(.882 .059 254.128);--comm-color-blue-300:oklch(.809 .105 251.813);--comm-color-blue-400:oklch(.707 .165 254.624);--comm-color-blue-500:oklch(.623 .214 259.815);--comm-color-blue-600:oklch(.546 .245 262.881);--comm-color-blue-700:oklch(.488 .243 264.376);--comm-color-blue-800:oklch(.424 .199 265.638);--comm-color-blue-900:oklch(.379 .146 265.522);--comm-color-blue-950:oklch(.282 .091 267.935);--comm-color-indigo-50:oklch(.962 .018 272.314);--comm-color-indigo-100:oklch(.93 .034 272.788);--comm-color-indigo-200:oklch(.87 .065 274.039);--comm-color-indigo-300:oklch(.785 .115 274.713);--comm-color-indigo-400:oklch(.673 .182 276.935);--comm-color-indigo-500:oklch(.585 .233 277.117);--comm-color-indigo-600:oklch(.511 .262 276.966);--comm-color-indigo-700:oklch(.457 .24 277.023);--comm-color-indigo-800:oklch(.398 .195 277.366);--comm-color-indigo-900:oklch(.359 .144 278.697);--comm-color-indigo-950:oklch(.257 .09 281.288);--comm-color-violet-50:oklch(.969 .016 293.756);--comm-color-violet-100:oklch(.943 .029 294.588);--comm-color-violet-200:oklch(.894 .057 293.283);--comm-color-violet-300:oklch(.811 .111 293.571);--comm-color-violet-400:oklch(.702 .183 293.541);--comm-color-violet-500:oklch(.606 .25 292.717);--comm-color-violet-600:oklch(.541 .281 293.009);--comm-color-violet-700:oklch(.491 .27 292.581);--comm-color-violet-800:oklch(.432 .232 292.759);--comm-color-violet-900:oklch(.38 .189 293.745);--comm-color-violet-950:oklch(.283 .141 291.089);--comm-color-purple-50:oklch(.977 .014 308.299);--comm-color-purple-100:oklch(.946 .033 307.174);--comm-color-purple-200:oklch(.902 .063 306.703);--comm-color-purple-300:oklch(.827 .119 306.383);--comm-color-purple-400:oklch(.714 .203 305.504);--comm-color-purple-500:oklch(.627 .265 303.9);--comm-color-purple-600:oklch(.558 .288 302.321);--comm-color-purple-700:oklch(.496 .265 301.924);--comm-color-purple-800:oklch(.438 .218 303.724);--comm-color-purple-900:oklch(.381 .176 304.987);--comm-color-purple-950:oklch(.291 .149 302.717);--comm-color-fuchsia-50:oklch(.977 .017 320.058);--comm-color-fuchsia-100:oklch(.952 .037 318.852);--comm-color-fuchsia-200:oklch(.903 .076 319.62);--comm-color-fuchsia-300:oklch(.833 .145 321.434);--comm-color-fuchsia-400:oklch(.74 .238 322.16);--comm-color-fuchsia-500:oklch(.667 .295 322.15);--comm-color-fuchsia-600:oklch(.591 .293 322.896);--comm-color-fuchsia-700:oklch(.518 .253 323.949);--comm-color-fuchsia-800:oklch(.452 .211 324.591);--comm-color-fuchsia-900:oklch(.401 .17 325.612);--comm-color-fuchsia-950:oklch(.293 .136 325.661);--comm-color-pink-50:oklch(.971 .014 343.198);--comm-color-pink-100:oklch(.948 .028 342.258);--comm-color-pink-200:oklch(.899 .061 343.231);--comm-color-pink-300:oklch(.823 .12 346.018);--comm-color-pink-400:oklch(.718 .202 349.761);--comm-color-pink-500:oklch(.656 .241 354.308);--comm-color-pink-600:oklch(.592 .249 .584);--comm-color-pink-700:oklch(.525 .223 3.958);--comm-color-pink-800:oklch(.459 .187 3.815);--comm-color-pink-900:oklch(.408 .153 2.432);--comm-color-pink-950:oklch(.284 .109 3.907);--comm-color-rose-50:oklch(.969 .015 12.422);--comm-color-rose-100:oklch(.941 .03 12.58);--comm-color-rose-200:oklch(.892 .058 10.001);--comm-color-rose-300:oklch(.81 .117 11.638);--comm-color-rose-400:oklch(.712 .194 13.428);--comm-color-rose-500:oklch(.645 .246 16.439);--comm-color-rose-600:oklch(.586 .253 17.585);--comm-color-rose-700:oklch(.514 .222 16.935);--comm-color-rose-800:oklch(.455 .188 13.697);--comm-color-rose-900:oklch(.41 .159 10.272);--comm-color-rose-950:oklch(.271 .105 12.094);--comm-color-slate-50:oklch(.984 .003 247.858);--comm-color-slate-100:oklch(.968 .007 247.896);--comm-color-slate-200:oklch(.929 .013 255.508);--comm-color-slate-300:oklch(.869 .022 252.894);--comm-color-slate-400:oklch(.704 .04 256.788);--comm-color-slate-500:oklch(.554 .046 257.417);--comm-color-slate-600:oklch(.446 .043 257.281);--comm-color-slate-700:oklch(.372 .044 257.287);--comm-color-slate-800:oklch(.279 .041 260.031);--comm-color-slate-900:oklch(.208 .042 265.755);--comm-color-slate-950:oklch(.129 .042 264.695);--comm-color-gray-50:oklch(.985 .002 247.839);--comm-color-gray-100:oklch(.967 .003 264.542);--comm-color-gray-200:oklch(.928 .006 264.531);--comm-color-gray-300:oklch(.872 .01 258.338);--comm-color-gray-400:oklch(.707 .022 261.325);--comm-color-gray-500:oklch(.551 .027 264.364);--comm-color-gray-600:oklch(.446 .03 256.802);--comm-color-gray-700:oklch(.373 .034 259.733);--comm-color-gray-800:oklch(.278 .033 256.848);--comm-color-gray-900:oklch(.21 .034 264.665);--comm-color-gray-950:oklch(.13 .028 261.692);--comm-color-zinc-50:oklch(.985 0 0);--comm-color-zinc-100:oklch(.967 .001 286.375);--comm-color-zinc-200:oklch(.92 .004 286.32);--comm-color-zinc-300:oklch(.871 .006 286.286);--comm-color-zinc-400:oklch(.705 .015 286.067);--comm-color-zinc-500:oklch(.552 .016 285.938);--comm-color-zinc-600:oklch(.442 .017 285.786);--comm-color-zinc-700:oklch(.37 .013 285.805);--comm-color-zinc-800:oklch(.274 .006 286.033);--comm-color-zinc-900:oklch(.21 .006 285.885);--comm-color-zinc-950:oklch(.141 .005 285.823);--comm-color-neutral-50:oklch(.985 0 0);--comm-color-neutral-100:oklch(.97 0 0);--comm-color-neutral-200:oklch(.922 0 0);--comm-color-neutral-300:oklch(.87 0 0);--comm-color-neutral-400:oklch(.708 0 0);--comm-color-neutral-500:oklch(.556 0 0);--comm-color-neutral-600:oklch(.439 0 0);--comm-color-neutral-700:oklch(.371 0 0);--comm-color-neutral-800:oklch(.269 0 0);--comm-color-neutral-900:oklch(.205 0 0);--comm-color-neutral-950:oklch(.145 0 0);--comm-color-stone-50:oklch(.985 .001 106.423);--comm-color-stone-100:oklch(.97 .001 106.424);--comm-color-stone-200:oklch(.923 .003 48.717);--comm-color-stone-300:oklch(.869 .005 56.366);--comm-color-stone-400:oklch(.709 .01 56.259);--comm-color-stone-500:oklch(.553 .013 58.071);--comm-color-stone-600:oklch(.444 .011 73.639);--comm-color-stone-700:oklch(.374 .01 67.558);--comm-color-stone-800:oklch(.268 .007 34.298);--comm-color-stone-900:oklch(.216 .006 56.043);--comm-color-stone-950:oklch(.147 .004 49.25);--comm-color-black:#000;--comm-color-white:#fff;--comm-spacing:.25rem;--comm-breakpoint-sm:40rem;--comm-breakpoint-md:48rem;--comm-breakpoint-lg:64rem;--comm-breakpoint-xl:80rem;--comm-breakpoint-2xl:96rem;--comm-container-3xs:16rem;--comm-container-2xs:18rem;--comm-container-xs:20rem;--comm-container-sm:24rem;--comm-container-md:28rem;--comm-container-lg:32rem;--comm-container-xl:36rem;--comm-container-2xl:42rem;--comm-container-3xl:48rem;--comm-container-4xl:56rem;--comm-container-5xl:64rem;--comm-container-6xl:72rem;--comm-container-7xl:80rem;--comm-text-xs:.75rem;--comm-text-xs--line-height:calc(1/.75);--comm-text-sm:.875rem;--comm-text-sm--line-height:calc(1.25/.875);--comm-text-base:1rem;--comm-text-base--line-height:calc(1.5/1);--comm-text-lg:1.125rem;--comm-text-lg--line-height:calc(1.75/1.125);--comm-text-xl:1.25rem;--comm-text-xl--line-height:calc(1.75/1.25);--comm-text-2xl:1.5rem;--comm-text-2xl--line-height:calc(2/1.5);--comm-text-3xl:1.875rem;--comm-text-3xl--line-height:calc(2.25/1.875);--comm-text-4xl:2.25rem;--comm-text-4xl--line-height:calc(2.5/2.25);--comm-text-5xl:3rem;--comm-text-5xl--line-height:1;--comm-text-6xl:3.75rem;--comm-text-6xl--line-height:1;--comm-text-7xl:4.5rem;--comm-text-7xl--line-height:1;--comm-text-8xl:6rem;--comm-text-8xl--line-height:1;--comm-text-9xl:8rem;--comm-text-9xl--line-height:1;--comm-font-weight-thin:100;--comm-font-weight-extralight:200;--comm-font-weight-light:300;--comm-font-weight-normal:400;--comm-font-weight-medium:500;--comm-font-weight-semibold:600;--comm-font-weight-bold:700;--comm-font-weight-extrabold:800;--comm-font-weight-black:900;--comm-tracking-tighter:-.05em;--comm-tracking-tight:-.025em;--comm-tracking-normal:0em;--comm-tracking-wide:.025em;--comm-tracking-wider:.05em;--comm-tracking-widest:.1em;--comm-leading-tight:1.25;--comm-leading-snug:1.375;--comm-leading-normal:1.5;--comm-leading-relaxed:1.625;--comm-leading-loose:2;--comm-radius-xs:.125rem;--comm-radius-sm:.25rem;--comm-radius-md:.375rem;--comm-radius-lg:.5rem;--comm-radius-xl:.75rem;--comm-radius-2xl:1rem;--comm-radius-3xl:1.5rem;--comm-radius-4xl:2rem;--comm-shadow-2xs:0 1px #0000000d;--comm-shadow-xs:0 1px 2px 0 #0000000d;--comm-shadow-sm:0 1px 3px 0 #0000001a,0 1px 2px -1px #0000001a;--comm-shadow-md:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a;--comm-shadow-lg:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;--comm-shadow-xl:0 20px 25px -5px #0000001a,0 8px 10px -6px #0000001a;--comm-shadow-2xl:0 25px 50px -12px #00000040;--comm-inset-shadow-2xs:inset 0 1px #0000000d;--comm-inset-shadow-xs:inset 0 1px 1px #0000000d;--comm-inset-shadow-sm:inset 0 2px 4px #0000000d;--comm-drop-shadow-xs:0 1px 1px #0000000d;--comm-drop-shadow-sm:0 1px 2px #00000026;--comm-drop-shadow-md:0 3px 3px #0000001f;--comm-drop-shadow-lg:0 4px 4px #00000026;--comm-drop-shadow-xl:0 9px 7px #0000001a;--comm-drop-shadow-2xl:0 25px 25px #00000026;--comm-ease-in:cubic-bezier(.4,0,1,1);--comm-ease-out:cubic-bezier(0,0,.2,1);--comm-ease-in-out:cubic-bezier(.4,0,.2,1);--comm-animate-spin:spin 1s linear infinite;--comm-animate-ping:ping 1s cubic-bezier(0,0,.2,1)infinite;--comm-animate-pulse:pulse 2s cubic-bezier(.4,0,.6,1)infinite;--comm-animate-bounce:bounce 1s infinite;--comm-blur-xs:4px;--comm-blur-sm:8px;--comm-blur-md:12px;--comm-blur-lg:16px;--comm-blur-xl:24px;--comm-blur-2xl:40px;--comm-blur-3xl:64px;--comm-perspective-dramatic:100px;--comm-perspective-near:300px;--comm-perspective-normal:500px;--comm-perspective-midrange:800px;--comm-perspective-distant:1200px;--comm-aspect-video:16/9;--comm-default-transition-duration:.15s;--comm-default-transition-timing-function:cubic-bezier(.4,0,.2,1);--comm-default-font-family:var(--font-sans);--comm-default-font-feature-settings:var(--font-sans--font-feature-settings);--comm-default-font-variation-settings:var(--font-sans--font-variation-settings);--comm-default-mono-font-family:var(--font-mono);--comm-default-mono-font-feature-settings:var(--font-mono--font-feature-settings);--comm-default-mono-font-variation-settings:var(--font-mono--font-variation-settings)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}body{line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1;color:color-mix(in oklab,currentColor 50%,transparent)}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.comm\:absolute{position:absolute!important}.comm\:relative{position:relative!important}.comm\:sticky{position:sticky!important}.comm\:top-4{top:calc(var(--comm-spacing)*4)!important}.comm\:bottom-full{bottom:100%!important}.comm\:z-10{z-index:10!important}.comm\:mt-0\.5{margin-top:calc(var(--comm-spacing)*.5)!important}.comm\:mt-1{margin-top:calc(var(--comm-spacing)*1)!important}.comm\:mt-2{margin-top:calc(var(--comm-spacing)*2)!important}.comm\:mt-3{margin-top:calc(var(--comm-spacing)*3)!important}.comm\:mb-2{margin-bottom:calc(var(--comm-spacing)*2)!important}.comm\:mb-3{margin-bottom:calc(var(--comm-spacing)*3)!important}.comm\:ml-1{margin-left:calc(var(--comm-spacing)*1)!important}.comm\:ml-2{margin-left:calc(var(--comm-spacing)*2)!important}.comm\:flex{display:flex!important}.comm\:hidden{display:none!important}.comm\:inline-block{display:inline-block!important}.comm\:inline-flex{display:inline-flex!important}.comm\:h-3{height:calc(var(--comm-spacing)*3)!important}.comm\:h-4{height:calc(var(--comm-spacing)*4)!important}.comm\:h-8{height:calc(var(--comm-spacing)*8)!important}.comm\:h-10{height:calc(var(--comm-spacing)*10)!important}.comm\:h-full{height:100%!important}.comm\:w-3{width:calc(var(--comm-spacing)*3)!important}.comm\:w-4{width:calc(var(--comm-spacing)*4)!important}.comm\:w-8{width:calc(var(--comm-spacing)*8)!important}.comm\:w-10{width:calc(var(--comm-spacing)*10)!important}.comm\:w-48{width:calc(var(--comm-spacing)*48)!important}.comm\:w-full{width:100%!important}.comm\:w-max{width:max-content!important}.comm\:max-w-xs{max-width:var(--comm-container-xs)!important}.comm\:min-w-full{min-width:100%!important}.comm\:flex-1{flex:1!important}.comm\:flex-shrink-0{flex-shrink:0!important}.comm\:flex-col{flex-direction:column!important}.comm\:flex-wrap{flex-wrap:wrap!important}.comm\:items-center{align-items:center!important}.comm\:items-start{align-items:flex-start!important}.comm\:justify-between{justify-content:space-between!important}.comm\:justify-center{justify-content:center!important}.comm\:justify-end{justify-content:flex-end!important}.comm\:gap-1{gap:calc(var(--comm-spacing)*1)!important}.comm\:gap-2{gap:calc(var(--comm-spacing)*2)!important}.comm\:gap-4{gap:calc(var(--comm-spacing)*4)!important}.comm\:gap-x-1{column-gap:calc(var(--comm-spacing)*1)!important}.comm\:gap-x-2{column-gap:calc(var(--comm-spacing)*2)!important}.comm\:gap-x-4{column-gap:calc(var(--comm-spacing)*4)!important}:where(.comm\:space-y-1>:not(:last-child)){--tw-space-y-reverse:0!important;margin-block-start:calc(calc(var(--comm-spacing)*1)*var(--tw-space-y-reverse))!important;margin-block-end:calc(calc(var(--comm-spacing)*1)*calc(1 - var(--tw-space-y-reverse)))!important}:where(.comm\:space-y-2>:not(:last-child)){--tw-space-y-reverse:0!important;margin-block-start:calc(calc(var(--comm-spacing)*2)*var(--tw-space-y-reverse))!important;margin-block-end:calc(calc(var(--comm-spacing)*2)*calc(1 - var(--tw-space-y-reverse)))!important}:where(.comm\:space-y-6>:not(:last-child)){--tw-space-y-reverse:0!important;margin-block-start:calc(calc(var(--comm-spacing)*6)*var(--tw-space-y-reverse))!important;margin-block-end:calc(calc(var(--comm-spacing)*6)*calc(1 - var(--tw-space-y-reverse)))!important}.comm\:gap-y-2{row-gap:calc(var(--comm-spacing)*2)!important}.comm\:truncate{text-overflow:ellipsis!important;white-space:nowrap!important;overflow:hidden!important}.comm\:rounded-full{border-radius:3.40282e38px!important}.comm\:rounded-lg{border-radius:var(--comm-radius-lg)!important}.comm\:rounded-md{border-radius:var(--comm-radius-md)!important}.comm\:border{border-style:var(--tw-border-style)!important;border-width:1px!important}.comm\:border-t{border-top-style:var(--tw-border-style)!important;border-top-width:1px!important}.comm\:border-l{border-left-style:var(--tw-border-style)!important;border-left-width:1px!important}.comm\:border-dashed{--tw-border-style:dashed!important;border-style:dashed!important}.comm\:border-gray-200{border-color:var(--comm-color-gray-200)!important}.comm\:border-gray-300{border-color:var(--comm-color-gray-300)!important}.comm\:bg-blue-100{background-color:var(--comm-color-blue-100)!important}.comm\:bg-gray-50{background-color:var(--comm-color-gray-50)!important}.comm\:bg-gray-100{background-color:var(--comm-color-gray-100)!important}.comm\:bg-gray-300{background-color:var(--comm-color-gray-300)!important}.comm\:bg-white{background-color:var(--comm-color-white)!important}.comm\:object-cover{object-fit:cover!important}.comm\:object-center{object-position:center!important}.comm\:p-1{padding:calc(var(--comm-spacing)*1)!important}.comm\:p-2{padding:calc(var(--comm-spacing)*2)!important}.comm\:p-4{padding:calc(var(--comm-spacing)*4)!important}.comm\:p-6{padding:calc(var(--comm-spacing)*6)!important}.comm\:px-1\.5{padding-inline:calc(var(--comm-spacing)*1.5)!important}.comm\:px-2{padding-inline:calc(var(--comm-spacing)*2)!important}.comm\:py-0\.5{padding-block:calc(var(--comm-spacing)*.5)!important}.comm\:py-4{padding-block:calc(var(--comm-spacing)*4)!important}.comm\:pt-2{padding-top:calc(var(--comm-spacing)*2)!important}.comm\:pt-3{padding-top:calc(var(--comm-spacing)*3)!important}.comm\:pl-2{padding-left:calc(var(--comm-spacing)*2)!important}.comm\:pl-3{padding-left:calc(var(--comm-spacing)*3)!important}.comm\:pl-6{padding-left:calc(var(--comm-spacing)*6)!important}.comm\:text-center{text-align:center!important}.comm\:text-sm{font-size:var(--comm-text-sm)!important;line-height:var(--tw-leading,var(--comm-text-sm--line-height))!important}.comm\:text-xs{font-size:var(--comm-text-xs)!important;line-height:var(--tw-leading,var(--comm-text-xs--line-height))!important}.comm\:font-bold{--tw-font-weight:var(--comm-font-weight-bold)!important;font-weight:var(--comm-font-weight-bold)!important}.comm\:font-medium{--tw-font-weight:var(--comm-font-weight-medium)!important;font-weight:var(--comm-font-weight-medium)!important}.comm\:whitespace-nowrap{white-space:nowrap!important}.comm\:text-gray-300{color:var(--comm-color-gray-300)!important}.comm\:text-gray-400{color:var(--comm-color-gray-400)!important}.comm\:text-gray-500{color:var(--comm-color-gray-500)!important}.comm\:text-gray-600{color:var(--comm-color-gray-600)!important}.comm\:text-gray-700{color:var(--comm-color-gray-700)!important}.comm\:text-gray-800{color:var(--comm-color-gray-800)!important}.comm\:text-gray-900{color:var(--comm-color-gray-900)!important}.comm\:shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a)!important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important}.comm\:shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a)!important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important}.comm\:transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter!important;transition-timing-function:var(--tw-ease,var(--comm-default-transition-timing-function))!important;transition-duration:var(--tw-duration,var(--comm-default-transition-duration))!important}@media (hover:hover){.comm\:hover\:bg-gray-100:hover{background-color:var(--comm-color-gray-100)!important}.comm\:hover\:bg-gray-200:hover{background-color:var(--comm-color-gray-200)!important}}.comm\:focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentColor)!important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important}.comm\:focus\:ring-offset-2:focus{--tw-ring-offset-width:2px!important;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)!important}.comm\:focus\:outline-none:focus{--tw-outline-style:none!important;outline-style:none!important}.comm\:disabled\:cursor-not-allowed:disabled{cursor:not-allowed!important}.comm\:disabled\:opacity-50:disabled{opacity:.5!important}.comm\:dark\:border-gray-600:where(.dark,.dark *){border-color:var(--comm-color-gray-600)!important}.comm\:dark\:border-gray-700:where(.dark,.dark *){border-color:var(--comm-color-gray-700)!important}.comm\:dark\:bg-gray-600:where(.dark,.dark *){background-color:var(--comm-color-gray-600)!important}.comm\:dark\:bg-gray-800:where(.dark,.dark *){background-color:var(--comm-color-gray-800)!important}.comm\:dark\:bg-gray-900:where(.dark,.dark *){background-color:var(--comm-color-gray-900)!important}.comm\:dark\:text-gray-100:where(.dark,.dark *){color:var(--comm-color-gray-100)!important}.comm\:dark\:text-gray-200:where(.dark,.dark *){color:var(--comm-color-gray-200)!important}.comm\:dark\:text-gray-300:where(.dark,.dark *){color:var(--comm-color-gray-300)!important}.comm\:dark\:text-gray-400:where(.dark,.dark *){color:var(--comm-color-gray-400)!important}.comm\:dark\:text-gray-500:where(.dark,.dark *){color:var(--comm-color-gray-500)!important}@media (hover:hover){.comm\:dark\:hover\:bg-gray-600:where(.dark,.dark *):hover{background-color:var(--comm-color-gray-600)!important}.comm\:dark\:hover\:bg-gray-700:where(.dark,.dark *):hover{background-color:var(--comm-color-gray-700)!important}}}[x-cloak]{display:none}.tiptap{font-size:var(--comm-text-sm)!important;line-height:var(--tw-leading,var(--comm-text-sm--line-height))!important;--tw-leading:var(--comm-leading-normal)!important;line-height:var(--comm-leading-normal)!important}.tiptap p.is-editor-empty:before{color:#adb5bd;content:attr(data-placeholder);float:inline-start;pointer-events:none;height:0}.tiptap .mention{background-color:var(--comm-color-gray-200)!important;padding-inline:calc(var(--comm-spacing)*1)!important;padding-block:calc(var(--comm-spacing)*.5)!important;--tw-font-weight:var(--comm-font-weight-bold)!important;font-weight:var(--comm-font-weight-bold)!important;color:var(--comm-color-blue-500)!important;border-radius:.25rem!important;display:inline-block!important}.mention-suggestion{z-index:1000;background:#fff;border:1px solid #ddd;border-radius:5px;max-height:150px;padding:5px;overflow-y:auto}.mention-item{cursor:pointer;padding:5px 10px}.mention-item:hover{background-color:var(--comm-color-gray-100)!important}@keyframes spin{to{transform:rotate(360deg)}}@keyframes ping{75%,to{opacity:0;transform:scale(2)}}@keyframes pulse{50%{opacity:.5}}@keyframes bounce{0%,to{animation-timing-function:cubic-bezier(.8,0,1,1);transform:translateY(-25%)}50%{animation-timing-function:cubic-bezier(0,0,.2,1);transform:none}}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-leading{syntax:"*";inherits:false} \ No newline at end of file diff --git a/resources/lang/ar/comments.php b/resources/lang/ar/comments.php index ddf3e4e..7281f12 100644 --- a/resources/lang/ar/comments.php +++ b/resources/lang/ar/comments.php @@ -16,6 +16,7 @@ 'cancel' => 'إلغاء', 'delete' => 'حذف', + 'reply' => 'رد', 'save' => 'حفظ', 'comment' => 'تعليق', 'add_reaction' => 'إضافة رد فعل', diff --git a/resources/lang/en/comments.php b/resources/lang/en/comments.php index 77dc525..cee9cb2 100644 --- a/resources/lang/en/comments.php +++ b/resources/lang/en/comments.php @@ -16,6 +16,7 @@ 'cancel' => 'Cancel', 'delete' => 'Delete', + 'reply' => 'Reply', 'save' => 'Save', 'comment' => 'Comment', 'add_reaction' => 'Add Reaction', diff --git a/resources/lang/es/comments.php b/resources/lang/es/comments.php index 99d02de..9399068 100644 --- a/resources/lang/es/comments.php +++ b/resources/lang/es/comments.php @@ -16,6 +16,7 @@ 'cancel' => 'Cancelar', 'delete' => 'Eliminar', + 'reply' => 'Responder', 'save' => 'Guardar', 'comment' => 'Comentar', 'add_reaction' => 'Agregar reacción', diff --git a/resources/lang/fr/comments.php b/resources/lang/fr/comments.php index ea38080..3117f14 100644 --- a/resources/lang/fr/comments.php +++ b/resources/lang/fr/comments.php @@ -16,6 +16,7 @@ 'cancel' => 'Annuler', 'delete' => 'Supprimer', + 'reply' => 'Répondre', 'save' => 'Enregistrer', 'comment' => 'Commenter', 'add_reaction' => 'Ajouter une réaction', diff --git a/resources/lang/nl/comments.php b/resources/lang/nl/comments.php index 187446a..365b899 100644 --- a/resources/lang/nl/comments.php +++ b/resources/lang/nl/comments.php @@ -15,6 +15,7 @@ 'cancel' => 'Annuleren', 'delete' => 'Verwijderen', + 'reply' => 'Beantwoorden', 'save' => 'Opslaan', 'comment' => 'Opmerking', 'add_reaction' => 'Reactie toevoegen', diff --git a/resources/lang/ro/comments.php b/resources/lang/ro/comments.php index a3c0ff4..dc17de6 100644 --- a/resources/lang/ro/comments.php +++ b/resources/lang/ro/comments.php @@ -16,6 +16,7 @@ 'cancel' => 'Anulare', 'delete' => 'Șterge', + 'reply' => 'Răspunde', 'save' => 'Salvare', 'comment' => 'Comentariu', 'add_reaction' => 'Adaugă reacție', diff --git a/resources/views/comment.blade.php b/resources/views/comment.blade.php index 8c880f3..7db7ef3 100644 --- a/resources/views/comment.blade.php +++ b/resources/views/comment.blade.php @@ -34,8 +34,17 @@ class="comm:text-xs comm:text-gray-300 comm:ml-1" @endif - @if ($comment->isComment() && Config::resolveAuthenticatedUser()?->canAny(['update', 'delete'], $comment)) + @if ($comment->isComment() && ($this->canReply() || Config::resolveAuthenticatedUser()?->canAny(['update', 'delete'], $comment)))
+ @if ($this->canReply()) + + @endif + @if (Config::resolveAuthenticatedUser()?->can('update', $comment)) @endif + + @if ($replying) +
+
+
+
+
+
+ +
+ + {{ __('commentions::comments.reply') }} + + + + {{ __('commentions::comments.cancel') }} + +
+
+ @endif + + @if ($comment->isComment() && config('commentions.threading.enabled', false) && $comment->replies->isNotEmpty()) +
+ @foreach ($comment->replies as $reply) + + @endforeach +
+ @endif @endif
diff --git a/src/Actions/SaveComment.php b/src/Actions/SaveComment.php index e4d45ae..97a17d1 100644 --- a/src/Actions/SaveComment.php +++ b/src/Actions/SaveComment.php @@ -16,17 +16,23 @@ class SaveComment /** * @throws AuthorizationException */ - public function __invoke(Model $commentable, Commenter $author, string $body): Comment + public function __invoke(Model $commentable, Commenter $author, string $body, ?int $parentId = null): Comment { if ($author->cannot('create', Config::getCommentModel())) { throw new AuthorizationException('Cannot create comment'); } - $comment = $commentable->comments()->create([ + $attributes = [ 'body' => $body, 'author_id' => $author->getKey(), 'author_type' => $author->getMorphClass(), - ]); + ]; + + if ($parentId !== null) { + $attributes['parent_id'] = $parentId; + } + + $comment = $commentable->comments()->create($attributes); $this->dispatchEvents($comment); diff --git a/src/Comment.php b/src/Comment.php index 91eca58..7ca68de 100644 --- a/src/Comment.php +++ b/src/Comment.php @@ -10,6 +10,7 @@ use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\MorphTo; use Illuminate\Support\Collection; @@ -23,6 +24,7 @@ /** * @property int $id + * @property int|null $parent_id * @property string $body * @property string $body_markdown * @property string $body_parsed @@ -37,6 +39,7 @@ class Comment extends Model implements RenderableComment use HasFactory; protected $fillable = [ + 'parent_id', 'body', 'author_type', 'author_id', @@ -165,6 +168,34 @@ public function reactions(): HasMany return $this->hasMany(CommentReaction::class); } + /** @return BelongsTo */ + public function parent(): BelongsTo + { + return $this->belongsTo(static::class, 'parent_id'); + } + + /** @return HasMany */ + public function replies(): HasMany + { + return $this->hasMany(static::class, 'parent_id')->oldest(); + } + + /** + * The nesting depth of this comment — 0 for a top-level comment. + */ + public function depth(): int + { + $depth = 0; + $parent = $this->parent; + + while ($parent !== null) { + $depth++; + $parent = $parent->parent; + } + + return $depth; + } + public function toggleReaction(string $reaction): void { ToggleCommentReaction::run($this, $reaction, Config::resolveAuthenticatedUser()); @@ -183,6 +214,13 @@ public function getContentHash(): string ])); } + protected static function booted(): void + { + static::deleting(function (Comment $comment): void { + $comment->replies()->get()->each->delete(); + }); + } + protected static function newFactory() { return CommentFactory::new(); diff --git a/src/CommentionsServiceProvider.php b/src/CommentionsServiceProvider.php index 593a66e..0e3263f 100644 --- a/src/CommentionsServiceProvider.php +++ b/src/CommentionsServiceProvider.php @@ -40,6 +40,7 @@ public function configurePackage(Package $package): void 'create_commentions_tables', 'create_commentions_reactions_table', 'create_commentions_subscriptions_table', + 'add_parent_id_to_commentions_comments_table', ]); } diff --git a/src/HasComments.php b/src/HasComments.php index 25d349c..9283b3a 100644 --- a/src/HasComments.php +++ b/src/HasComments.php @@ -16,9 +16,17 @@ public function comments(): MorphMany public function commentsQuery(): MorphMany { - return $this->comments() + $query = $this->comments() ->latest() ->with(['author', 'reactions.reactor']); + + if (config('commentions.threading.enabled', false)) { + $query + ->whereNull('parent_id') + ->with($this->threadedRepliesEagerLoad()); + } + + return $query; } public function comment(string $body, ?Commenter $author): Comment @@ -81,4 +89,26 @@ public function getSubscribers(): Collection }) ->filter(); } + + /** + * Eager-load paths for nested replies down to the configured max depth. + * + * @return array + */ + protected function threadedRepliesEagerLoad(): array + { + $maxDepth = max(0, (int) config('commentions.threading.max_depth', 3)); + + $paths = []; + $prefix = 'replies'; + + for ($level = 1; $level <= $maxDepth; $level++) { + $paths[] = $prefix; + $paths[] = $prefix . '.author'; + $paths[] = $prefix . '.reactions.reactor'; + $prefix .= '.replies'; + } + + return $paths; + } } diff --git a/src/Livewire/Comment.php b/src/Livewire/Comment.php index 82eb5e9..ac89ee9 100644 --- a/src/Livewire/Comment.php +++ b/src/Livewire/Comment.php @@ -4,6 +4,7 @@ use Filament\Notifications\Notification; use Illuminate\Contracts\View\View; +use Kirschbaum\Commentions\Actions\SaveComment; use Kirschbaum\Commentions\Comment as CommentModel; use Kirschbaum\Commentions\Config; use Kirschbaum\Commentions\Contracts\RenderableComment; @@ -22,6 +23,10 @@ class Comment extends Component public bool $editing = false; + public bool $replying = false; + + public int $depth = 0; + public ?string $tipTapCssClasses = null; protected $rules = [ @@ -106,6 +111,55 @@ public function cancelEditing() $this->commentBody = ''; } + public function reply(): void + { + if (! $this->comment instanceof CommentModel) { + return; + } + + $this->editing = false; + $this->replying = true; + $this->commentBody = ''; + } + + public function saveReply(): void + { + if (! $this->comment instanceof CommentModel) { + return; + } + + $user = Config::resolveAuthenticatedUser(); + + if (! $user) { + return; + } + + if ($this->comment->depth() >= $this->maxReplyDepth()) { + return; + } + + $this->validate(); + + SaveComment::run( + $this->comment->commentable, + $user, + $this->commentBody, + (int) $this->comment->getId(), + ); + + $this->replying = false; + $this->commentBody = ''; + + $this->dispatch('comment:saved'); + $this->dispatch('comment:content:cleared'); + } + + public function cancelReplying(): void + { + $this->replying = false; + $this->commentBody = ''; + } + #[Renderless] public function toggleReaction(string $reaction): void { @@ -122,4 +176,21 @@ public function getTipTapCssClasses(): ?string { return $this->tipTapCssClasses ?? Config::getTipTapCssClasses(); } + + /** + * Whether the current user may post a reply to this comment, given that + * threading is enabled and the comment is not already at the max depth. + */ + public function canReply(): bool + { + return $this->comment instanceof CommentModel + && (bool) config('commentions.threading.enabled', false) + && $this->depth < $this->maxReplyDepth() + && (bool) Config::resolveAuthenticatedUser()?->can('create', Config::getCommentModel()); + } + + protected function maxReplyDepth(): int + { + return max(0, (int) config('commentions.threading.max_depth', 3)); + } } diff --git a/tests/Livewire/CommentThreadingTest.php b/tests/Livewire/CommentThreadingTest.php new file mode 100644 index 0000000..c703988 --- /dev/null +++ b/tests/Livewire/CommentThreadingTest.php @@ -0,0 +1,145 @@ + Auth::user()); + config(['commentions.threading.enabled' => true]); +}); + +test('a comment can be created as a reply to another comment', function () { + $user = User::factory()->create(); + $post = Post::factory()->create(); + + $parent = Comment::factory()->author($user)->commentable($post)->create(); + + $reply = SaveComment::run($post, $user, 'A reply', $parent->id); + + expect($reply->parent_id)->toBe($parent->id) + ->and($parent->replies()->count())->toBe(1) + ->and($reply->parent->is($parent))->toBeTrue(); +}); + +test('comment depth reflects nesting', function () { + $user = User::factory()->create(); + $post = Post::factory()->create(); + + $a = Comment::factory()->author($user)->commentable($post)->create(); + $b = Comment::factory()->author($user)->commentable($post)->create(['parent_id' => $a->id]); + $c = Comment::factory()->author($user)->commentable($post)->create(['parent_id' => $b->id]); + + expect($a->depth())->toBe(0) + ->and($b->depth())->toBe(1) + ->and($c->depth())->toBe(2); +}); + +test('getComments returns only top-level comments when threading is enabled', function () { + $user = User::factory()->create(); + $post = Post::factory()->create(); + + $parent = Comment::factory()->author($user)->commentable($post)->create(); + Comment::factory()->author($user)->commentable($post)->create(['parent_id' => $parent->id]); + + expect($post->getComments())->toHaveCount(1) + ->and($post->getComments()->first()->replies)->toHaveCount(1); +}); + +test('getComments returns all comments flat when threading is disabled', function () { + config(['commentions.threading.enabled' => false]); + + $user = User::factory()->create(); + $post = Post::factory()->create(); + + $parent = Comment::factory()->author($user)->commentable($post)->create(); + Comment::factory()->author($user)->commentable($post)->create(['parent_id' => $parent->id]); + + expect($post->getComments())->toHaveCount(2); +}); + +test('the reply control saves a nested reply', function () { + $user = User::factory()->create(); + actingAs($user); + + $post = Post::factory()->create(); + $parent = Comment::factory()->author($user)->commentable($post)->create(); + + livewire(CommentComponent::class, ['comment' => $parent]) + ->call('reply') + ->assertSet('replying', true) + ->set('commentBody', 'My threaded reply') + ->call('saveReply') + ->assertSet('replying', false); + + expect($parent->replies()->count())->toBe(1) + ->and($parent->replies()->first()->body)->toBe('My threaded reply'); +}); + +test('the reply control is hidden when threading is disabled', function () { + config(['commentions.threading.enabled' => false]); + + $user = User::factory()->create(); + actingAs($user); + + $post = Post::factory()->create(); + $comment = Comment::factory()->author($user)->commentable($post)->create(); + + livewire(CommentComponent::class, ['comment' => $comment]) + ->assertDontSeeHtml('wire:click="reply"'); +}); + +test('the reply control is hidden once the max depth is reached', function () { + config(['commentions.threading.max_depth' => 1]); + + $user = User::factory()->create(); + actingAs($user); + + $post = Post::factory()->create(); + $parent = Comment::factory()->author($user)->commentable($post)->create(); + $reply = Comment::factory()->author($user)->commentable($post)->create(['parent_id' => $parent->id]); + + livewire(CommentComponent::class, ['comment' => $parent, 'depth' => 0]) + ->assertSeeHtml('wire:click="reply"'); + + livewire(CommentComponent::class, ['comment' => $reply, 'depth' => 1]) + ->assertDontSeeHtml('wire:click="reply"'); +}); + +test('replies beyond the max depth are not saved', function () { + config(['commentions.threading.max_depth' => 1]); + + $user = User::factory()->create(); + actingAs($user); + + $post = Post::factory()->create(); + $parent = Comment::factory()->author($user)->commentable($post)->create(); + $reply = Comment::factory()->author($user)->commentable($post)->create(['parent_id' => $parent->id]); + + livewire(CommentComponent::class, ['comment' => $reply, 'depth' => 1]) + ->set('commentBody', 'too deep') + ->call('saveReply'); + + expect($reply->replies()->count())->toBe(0); +}); + +test('deleting a comment deletes its nested replies', function () { + $user = User::factory()->create(); + $post = Post::factory()->create(); + + $parent = Comment::factory()->author($user)->commentable($post)->create(); + $reply = Comment::factory()->author($user)->commentable($post)->create(['parent_id' => $parent->id]); + $nested = Comment::factory()->author($user)->commentable($post)->create(['parent_id' => $reply->id]); + + $parent->delete(); + + test()->assertDatabaseMissing('comments', ['id' => $reply->id]); + test()->assertDatabaseMissing('comments', ['id' => $nested->id]); +}); diff --git a/tests/TestCase.php b/tests/TestCase.php index 226f557..c46dfdb 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -55,6 +55,7 @@ protected function setUpDatabase() __DIR__ . '/../database/migrations/create_commentions_tables.php.stub', __DIR__ . '/../database/migrations/create_commentions_reactions_table.php.stub', __DIR__ . '/../database/migrations/create_commentions_subscriptions_table.php.stub', + __DIR__ . '/../database/migrations/add_parent_id_to_commentions_comments_table.php.stub', ]; foreach ($migrations as $migration) { From 323ccf7a11c6bbd7c8a69bd82dd3c60b2d798e50 Mon Sep 17 00:00:00 2001 From: Malik Alleyne-Jones Date: Sun, 17 May 2026 14:19:43 -0400 Subject: [PATCH 2/2] Add threaded comment replies with collapsible UI - Add Facebook-style thread connector lines for nested replies - Implement collapsible replies with accessible toggle showing descendant count - Cap horizontal indentation at depth 2 to prevent layout issues on small screens - Add `repliesCount()` method to recursively count all descendant comments - Update CSS for thread lines with dark mode support - Add English translations for replies UI --- resources/css/commentions.css | 51 +++++++++++++ resources/dist/commentions.css | 2 +- resources/lang/en/comments.php | 2 + resources/views/comment.blade.php | 73 ++++++++++++++---- src/Comment.php | 11 +++ src/Livewire/Comment.php | 16 ++++ tests/Livewire/CommentThreadingTest.php | 99 +++++++++++++++++++++++++ 7 files changed, 240 insertions(+), 14 deletions(-) diff --git a/resources/css/commentions.css b/resources/css/commentions.css index 695c00d..19575e0 100644 --- a/resources/css/commentions.css +++ b/resources/css/commentions.css @@ -44,3 +44,54 @@ .mention-item:hover { @apply comm:bg-gray-100; } + +/* + * Threaded reply connector — a Facebook-style curved elbow line. + * Rendered by the `.commentions-thread` element inside each reply (depth > 0), + * which sits absolutely inside the reply row's left padding gutter. + */ +.commentions-thread { + position: absolute; + inset: 0 auto 0 0; + width: 1.5rem; + pointer-events: none; +} + +.commentions-thread::before, +.commentions-thread::after { + content: ""; + position: absolute; + left: 0.5rem; +} + +/* Vertical trunk running the full height of the reply row. */ +.commentions-thread::before { + top: 0; + bottom: 0; + width: 2px; + background-color: #d1d5db; +} + +/* Curved elbow branching off the trunk into the reply's avatar. */ +.commentions-thread::after { + top: 0; + width: 1rem; + height: 1.5rem; + border-left: 2px solid #d1d5db; + border-bottom: 2px solid #d1d5db; + border-bottom-left-radius: 0.75rem; +} + +/* The last reply ends the trunk at its own elbow rather than running on. */ +.commentions-replies > :last-child .commentions-thread::before { + bottom: auto; + height: 1.5rem; +} + +:where(.dark, .dark *) .commentions-thread::before { + background-color: #4b5563; +} + +:where(.dark, .dark *) .commentions-thread::after { + border-color: #4b5563; +} diff --git a/resources/dist/commentions.css b/resources/dist/commentions.css index fb62790..7ab5f64 100644 --- a/resources/dist/commentions.css +++ b/resources/dist/commentions.css @@ -1,2 +1,2 @@ /*! tailwindcss v4.0.6 | MIT License | https://tailwindcss.com */ -@layer theme{:root,:host{--comm-font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--comm-font-serif:ui-serif,Georgia,Cambria,"Times New Roman",Times,serif;--comm-font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--comm-color-red-50:oklch(.971 .013 17.38);--comm-color-red-100:oklch(.936 .032 17.717);--comm-color-red-200:oklch(.885 .062 18.334);--comm-color-red-300:oklch(.808 .114 19.571);--comm-color-red-400:oklch(.704 .191 22.216);--comm-color-red-500:oklch(.637 .237 25.331);--comm-color-red-600:oklch(.577 .245 27.325);--comm-color-red-700:oklch(.505 .213 27.518);--comm-color-red-800:oklch(.444 .177 26.899);--comm-color-red-900:oklch(.396 .141 25.723);--comm-color-red-950:oklch(.258 .092 26.042);--comm-color-orange-50:oklch(.98 .016 73.684);--comm-color-orange-100:oklch(.954 .038 75.164);--comm-color-orange-200:oklch(.901 .076 70.697);--comm-color-orange-300:oklch(.837 .128 66.29);--comm-color-orange-400:oklch(.75 .183 55.934);--comm-color-orange-500:oklch(.705 .213 47.604);--comm-color-orange-600:oklch(.646 .222 41.116);--comm-color-orange-700:oklch(.553 .195 38.402);--comm-color-orange-800:oklch(.47 .157 37.304);--comm-color-orange-900:oklch(.408 .123 38.172);--comm-color-orange-950:oklch(.266 .079 36.259);--comm-color-amber-50:oklch(.987 .022 95.277);--comm-color-amber-100:oklch(.962 .059 95.617);--comm-color-amber-200:oklch(.924 .12 95.746);--comm-color-amber-300:oklch(.879 .169 91.605);--comm-color-amber-400:oklch(.828 .189 84.429);--comm-color-amber-500:oklch(.769 .188 70.08);--comm-color-amber-600:oklch(.666 .179 58.318);--comm-color-amber-700:oklch(.555 .163 48.998);--comm-color-amber-800:oklch(.473 .137 46.201);--comm-color-amber-900:oklch(.414 .112 45.904);--comm-color-amber-950:oklch(.279 .077 45.635);--comm-color-yellow-50:oklch(.987 .026 102.212);--comm-color-yellow-100:oklch(.973 .071 103.193);--comm-color-yellow-200:oklch(.945 .129 101.54);--comm-color-yellow-300:oklch(.905 .182 98.111);--comm-color-yellow-400:oklch(.852 .199 91.936);--comm-color-yellow-500:oklch(.795 .184 86.047);--comm-color-yellow-600:oklch(.681 .162 75.834);--comm-color-yellow-700:oklch(.554 .135 66.442);--comm-color-yellow-800:oklch(.476 .114 61.907);--comm-color-yellow-900:oklch(.421 .095 57.708);--comm-color-yellow-950:oklch(.286 .066 53.813);--comm-color-lime-50:oklch(.986 .031 120.757);--comm-color-lime-100:oklch(.967 .067 122.328);--comm-color-lime-200:oklch(.938 .127 124.321);--comm-color-lime-300:oklch(.897 .196 126.665);--comm-color-lime-400:oklch(.841 .238 128.85);--comm-color-lime-500:oklch(.768 .233 130.85);--comm-color-lime-600:oklch(.648 .2 131.684);--comm-color-lime-700:oklch(.532 .157 131.589);--comm-color-lime-800:oklch(.453 .124 130.933);--comm-color-lime-900:oklch(.405 .101 131.063);--comm-color-lime-950:oklch(.274 .072 132.109);--comm-color-green-50:oklch(.982 .018 155.826);--comm-color-green-100:oklch(.962 .044 156.743);--comm-color-green-200:oklch(.925 .084 155.995);--comm-color-green-300:oklch(.871 .15 154.449);--comm-color-green-400:oklch(.792 .209 151.711);--comm-color-green-500:oklch(.723 .219 149.579);--comm-color-green-600:oklch(.627 .194 149.214);--comm-color-green-700:oklch(.527 .154 150.069);--comm-color-green-800:oklch(.448 .119 151.328);--comm-color-green-900:oklch(.393 .095 152.535);--comm-color-green-950:oklch(.266 .065 152.934);--comm-color-emerald-50:oklch(.979 .021 166.113);--comm-color-emerald-100:oklch(.95 .052 163.051);--comm-color-emerald-200:oklch(.905 .093 164.15);--comm-color-emerald-300:oklch(.845 .143 164.978);--comm-color-emerald-400:oklch(.765 .177 163.223);--comm-color-emerald-500:oklch(.696 .17 162.48);--comm-color-emerald-600:oklch(.596 .145 163.225);--comm-color-emerald-700:oklch(.508 .118 165.612);--comm-color-emerald-800:oklch(.432 .095 166.913);--comm-color-emerald-900:oklch(.378 .077 168.94);--comm-color-emerald-950:oklch(.262 .051 172.552);--comm-color-teal-50:oklch(.984 .014 180.72);--comm-color-teal-100:oklch(.953 .051 180.801);--comm-color-teal-200:oklch(.91 .096 180.426);--comm-color-teal-300:oklch(.855 .138 181.071);--comm-color-teal-400:oklch(.777 .152 181.912);--comm-color-teal-500:oklch(.704 .14 182.503);--comm-color-teal-600:oklch(.6 .118 184.704);--comm-color-teal-700:oklch(.511 .096 186.391);--comm-color-teal-800:oklch(.437 .078 188.216);--comm-color-teal-900:oklch(.386 .063 188.416);--comm-color-teal-950:oklch(.277 .046 192.524);--comm-color-cyan-50:oklch(.984 .019 200.873);--comm-color-cyan-100:oklch(.956 .045 203.388);--comm-color-cyan-200:oklch(.917 .08 205.041);--comm-color-cyan-300:oklch(.865 .127 207.078);--comm-color-cyan-400:oklch(.789 .154 211.53);--comm-color-cyan-500:oklch(.715 .143 215.221);--comm-color-cyan-600:oklch(.609 .126 221.723);--comm-color-cyan-700:oklch(.52 .105 223.128);--comm-color-cyan-800:oklch(.45 .085 224.283);--comm-color-cyan-900:oklch(.398 .07 227.392);--comm-color-cyan-950:oklch(.302 .056 229.695);--comm-color-sky-50:oklch(.977 .013 236.62);--comm-color-sky-100:oklch(.951 .026 236.824);--comm-color-sky-200:oklch(.901 .058 230.902);--comm-color-sky-300:oklch(.828 .111 230.318);--comm-color-sky-400:oklch(.746 .16 232.661);--comm-color-sky-500:oklch(.685 .169 237.323);--comm-color-sky-600:oklch(.588 .158 241.966);--comm-color-sky-700:oklch(.5 .134 242.749);--comm-color-sky-800:oklch(.443 .11 240.79);--comm-color-sky-900:oklch(.391 .09 240.876);--comm-color-sky-950:oklch(.293 .066 243.157);--comm-color-blue-50:oklch(.97 .014 254.604);--comm-color-blue-100:oklch(.932 .032 255.585);--comm-color-blue-200:oklch(.882 .059 254.128);--comm-color-blue-300:oklch(.809 .105 251.813);--comm-color-blue-400:oklch(.707 .165 254.624);--comm-color-blue-500:oklch(.623 .214 259.815);--comm-color-blue-600:oklch(.546 .245 262.881);--comm-color-blue-700:oklch(.488 .243 264.376);--comm-color-blue-800:oklch(.424 .199 265.638);--comm-color-blue-900:oklch(.379 .146 265.522);--comm-color-blue-950:oklch(.282 .091 267.935);--comm-color-indigo-50:oklch(.962 .018 272.314);--comm-color-indigo-100:oklch(.93 .034 272.788);--comm-color-indigo-200:oklch(.87 .065 274.039);--comm-color-indigo-300:oklch(.785 .115 274.713);--comm-color-indigo-400:oklch(.673 .182 276.935);--comm-color-indigo-500:oklch(.585 .233 277.117);--comm-color-indigo-600:oklch(.511 .262 276.966);--comm-color-indigo-700:oklch(.457 .24 277.023);--comm-color-indigo-800:oklch(.398 .195 277.366);--comm-color-indigo-900:oklch(.359 .144 278.697);--comm-color-indigo-950:oklch(.257 .09 281.288);--comm-color-violet-50:oklch(.969 .016 293.756);--comm-color-violet-100:oklch(.943 .029 294.588);--comm-color-violet-200:oklch(.894 .057 293.283);--comm-color-violet-300:oklch(.811 .111 293.571);--comm-color-violet-400:oklch(.702 .183 293.541);--comm-color-violet-500:oklch(.606 .25 292.717);--comm-color-violet-600:oklch(.541 .281 293.009);--comm-color-violet-700:oklch(.491 .27 292.581);--comm-color-violet-800:oklch(.432 .232 292.759);--comm-color-violet-900:oklch(.38 .189 293.745);--comm-color-violet-950:oklch(.283 .141 291.089);--comm-color-purple-50:oklch(.977 .014 308.299);--comm-color-purple-100:oklch(.946 .033 307.174);--comm-color-purple-200:oklch(.902 .063 306.703);--comm-color-purple-300:oklch(.827 .119 306.383);--comm-color-purple-400:oklch(.714 .203 305.504);--comm-color-purple-500:oklch(.627 .265 303.9);--comm-color-purple-600:oklch(.558 .288 302.321);--comm-color-purple-700:oklch(.496 .265 301.924);--comm-color-purple-800:oklch(.438 .218 303.724);--comm-color-purple-900:oklch(.381 .176 304.987);--comm-color-purple-950:oklch(.291 .149 302.717);--comm-color-fuchsia-50:oklch(.977 .017 320.058);--comm-color-fuchsia-100:oklch(.952 .037 318.852);--comm-color-fuchsia-200:oklch(.903 .076 319.62);--comm-color-fuchsia-300:oklch(.833 .145 321.434);--comm-color-fuchsia-400:oklch(.74 .238 322.16);--comm-color-fuchsia-500:oklch(.667 .295 322.15);--comm-color-fuchsia-600:oklch(.591 .293 322.896);--comm-color-fuchsia-700:oklch(.518 .253 323.949);--comm-color-fuchsia-800:oklch(.452 .211 324.591);--comm-color-fuchsia-900:oklch(.401 .17 325.612);--comm-color-fuchsia-950:oklch(.293 .136 325.661);--comm-color-pink-50:oklch(.971 .014 343.198);--comm-color-pink-100:oklch(.948 .028 342.258);--comm-color-pink-200:oklch(.899 .061 343.231);--comm-color-pink-300:oklch(.823 .12 346.018);--comm-color-pink-400:oklch(.718 .202 349.761);--comm-color-pink-500:oklch(.656 .241 354.308);--comm-color-pink-600:oklch(.592 .249 .584);--comm-color-pink-700:oklch(.525 .223 3.958);--comm-color-pink-800:oklch(.459 .187 3.815);--comm-color-pink-900:oklch(.408 .153 2.432);--comm-color-pink-950:oklch(.284 .109 3.907);--comm-color-rose-50:oklch(.969 .015 12.422);--comm-color-rose-100:oklch(.941 .03 12.58);--comm-color-rose-200:oklch(.892 .058 10.001);--comm-color-rose-300:oklch(.81 .117 11.638);--comm-color-rose-400:oklch(.712 .194 13.428);--comm-color-rose-500:oklch(.645 .246 16.439);--comm-color-rose-600:oklch(.586 .253 17.585);--comm-color-rose-700:oklch(.514 .222 16.935);--comm-color-rose-800:oklch(.455 .188 13.697);--comm-color-rose-900:oklch(.41 .159 10.272);--comm-color-rose-950:oklch(.271 .105 12.094);--comm-color-slate-50:oklch(.984 .003 247.858);--comm-color-slate-100:oklch(.968 .007 247.896);--comm-color-slate-200:oklch(.929 .013 255.508);--comm-color-slate-300:oklch(.869 .022 252.894);--comm-color-slate-400:oklch(.704 .04 256.788);--comm-color-slate-500:oklch(.554 .046 257.417);--comm-color-slate-600:oklch(.446 .043 257.281);--comm-color-slate-700:oklch(.372 .044 257.287);--comm-color-slate-800:oklch(.279 .041 260.031);--comm-color-slate-900:oklch(.208 .042 265.755);--comm-color-slate-950:oklch(.129 .042 264.695);--comm-color-gray-50:oklch(.985 .002 247.839);--comm-color-gray-100:oklch(.967 .003 264.542);--comm-color-gray-200:oklch(.928 .006 264.531);--comm-color-gray-300:oklch(.872 .01 258.338);--comm-color-gray-400:oklch(.707 .022 261.325);--comm-color-gray-500:oklch(.551 .027 264.364);--comm-color-gray-600:oklch(.446 .03 256.802);--comm-color-gray-700:oklch(.373 .034 259.733);--comm-color-gray-800:oklch(.278 .033 256.848);--comm-color-gray-900:oklch(.21 .034 264.665);--comm-color-gray-950:oklch(.13 .028 261.692);--comm-color-zinc-50:oklch(.985 0 0);--comm-color-zinc-100:oklch(.967 .001 286.375);--comm-color-zinc-200:oklch(.92 .004 286.32);--comm-color-zinc-300:oklch(.871 .006 286.286);--comm-color-zinc-400:oklch(.705 .015 286.067);--comm-color-zinc-500:oklch(.552 .016 285.938);--comm-color-zinc-600:oklch(.442 .017 285.786);--comm-color-zinc-700:oklch(.37 .013 285.805);--comm-color-zinc-800:oklch(.274 .006 286.033);--comm-color-zinc-900:oklch(.21 .006 285.885);--comm-color-zinc-950:oklch(.141 .005 285.823);--comm-color-neutral-50:oklch(.985 0 0);--comm-color-neutral-100:oklch(.97 0 0);--comm-color-neutral-200:oklch(.922 0 0);--comm-color-neutral-300:oklch(.87 0 0);--comm-color-neutral-400:oklch(.708 0 0);--comm-color-neutral-500:oklch(.556 0 0);--comm-color-neutral-600:oklch(.439 0 0);--comm-color-neutral-700:oklch(.371 0 0);--comm-color-neutral-800:oklch(.269 0 0);--comm-color-neutral-900:oklch(.205 0 0);--comm-color-neutral-950:oklch(.145 0 0);--comm-color-stone-50:oklch(.985 .001 106.423);--comm-color-stone-100:oklch(.97 .001 106.424);--comm-color-stone-200:oklch(.923 .003 48.717);--comm-color-stone-300:oklch(.869 .005 56.366);--comm-color-stone-400:oklch(.709 .01 56.259);--comm-color-stone-500:oklch(.553 .013 58.071);--comm-color-stone-600:oklch(.444 .011 73.639);--comm-color-stone-700:oklch(.374 .01 67.558);--comm-color-stone-800:oklch(.268 .007 34.298);--comm-color-stone-900:oklch(.216 .006 56.043);--comm-color-stone-950:oklch(.147 .004 49.25);--comm-color-black:#000;--comm-color-white:#fff;--comm-spacing:.25rem;--comm-breakpoint-sm:40rem;--comm-breakpoint-md:48rem;--comm-breakpoint-lg:64rem;--comm-breakpoint-xl:80rem;--comm-breakpoint-2xl:96rem;--comm-container-3xs:16rem;--comm-container-2xs:18rem;--comm-container-xs:20rem;--comm-container-sm:24rem;--comm-container-md:28rem;--comm-container-lg:32rem;--comm-container-xl:36rem;--comm-container-2xl:42rem;--comm-container-3xl:48rem;--comm-container-4xl:56rem;--comm-container-5xl:64rem;--comm-container-6xl:72rem;--comm-container-7xl:80rem;--comm-text-xs:.75rem;--comm-text-xs--line-height:calc(1/.75);--comm-text-sm:.875rem;--comm-text-sm--line-height:calc(1.25/.875);--comm-text-base:1rem;--comm-text-base--line-height:calc(1.5/1);--comm-text-lg:1.125rem;--comm-text-lg--line-height:calc(1.75/1.125);--comm-text-xl:1.25rem;--comm-text-xl--line-height:calc(1.75/1.25);--comm-text-2xl:1.5rem;--comm-text-2xl--line-height:calc(2/1.5);--comm-text-3xl:1.875rem;--comm-text-3xl--line-height:calc(2.25/1.875);--comm-text-4xl:2.25rem;--comm-text-4xl--line-height:calc(2.5/2.25);--comm-text-5xl:3rem;--comm-text-5xl--line-height:1;--comm-text-6xl:3.75rem;--comm-text-6xl--line-height:1;--comm-text-7xl:4.5rem;--comm-text-7xl--line-height:1;--comm-text-8xl:6rem;--comm-text-8xl--line-height:1;--comm-text-9xl:8rem;--comm-text-9xl--line-height:1;--comm-font-weight-thin:100;--comm-font-weight-extralight:200;--comm-font-weight-light:300;--comm-font-weight-normal:400;--comm-font-weight-medium:500;--comm-font-weight-semibold:600;--comm-font-weight-bold:700;--comm-font-weight-extrabold:800;--comm-font-weight-black:900;--comm-tracking-tighter:-.05em;--comm-tracking-tight:-.025em;--comm-tracking-normal:0em;--comm-tracking-wide:.025em;--comm-tracking-wider:.05em;--comm-tracking-widest:.1em;--comm-leading-tight:1.25;--comm-leading-snug:1.375;--comm-leading-normal:1.5;--comm-leading-relaxed:1.625;--comm-leading-loose:2;--comm-radius-xs:.125rem;--comm-radius-sm:.25rem;--comm-radius-md:.375rem;--comm-radius-lg:.5rem;--comm-radius-xl:.75rem;--comm-radius-2xl:1rem;--comm-radius-3xl:1.5rem;--comm-radius-4xl:2rem;--comm-shadow-2xs:0 1px #0000000d;--comm-shadow-xs:0 1px 2px 0 #0000000d;--comm-shadow-sm:0 1px 3px 0 #0000001a,0 1px 2px -1px #0000001a;--comm-shadow-md:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a;--comm-shadow-lg:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;--comm-shadow-xl:0 20px 25px -5px #0000001a,0 8px 10px -6px #0000001a;--comm-shadow-2xl:0 25px 50px -12px #00000040;--comm-inset-shadow-2xs:inset 0 1px #0000000d;--comm-inset-shadow-xs:inset 0 1px 1px #0000000d;--comm-inset-shadow-sm:inset 0 2px 4px #0000000d;--comm-drop-shadow-xs:0 1px 1px #0000000d;--comm-drop-shadow-sm:0 1px 2px #00000026;--comm-drop-shadow-md:0 3px 3px #0000001f;--comm-drop-shadow-lg:0 4px 4px #00000026;--comm-drop-shadow-xl:0 9px 7px #0000001a;--comm-drop-shadow-2xl:0 25px 25px #00000026;--comm-ease-in:cubic-bezier(.4,0,1,1);--comm-ease-out:cubic-bezier(0,0,.2,1);--comm-ease-in-out:cubic-bezier(.4,0,.2,1);--comm-animate-spin:spin 1s linear infinite;--comm-animate-ping:ping 1s cubic-bezier(0,0,.2,1)infinite;--comm-animate-pulse:pulse 2s cubic-bezier(.4,0,.6,1)infinite;--comm-animate-bounce:bounce 1s infinite;--comm-blur-xs:4px;--comm-blur-sm:8px;--comm-blur-md:12px;--comm-blur-lg:16px;--comm-blur-xl:24px;--comm-blur-2xl:40px;--comm-blur-3xl:64px;--comm-perspective-dramatic:100px;--comm-perspective-near:300px;--comm-perspective-normal:500px;--comm-perspective-midrange:800px;--comm-perspective-distant:1200px;--comm-aspect-video:16/9;--comm-default-transition-duration:.15s;--comm-default-transition-timing-function:cubic-bezier(.4,0,.2,1);--comm-default-font-family:var(--font-sans);--comm-default-font-feature-settings:var(--font-sans--font-feature-settings);--comm-default-font-variation-settings:var(--font-sans--font-variation-settings);--comm-default-mono-font-family:var(--font-mono);--comm-default-mono-font-feature-settings:var(--font-mono--font-feature-settings);--comm-default-mono-font-variation-settings:var(--font-mono--font-variation-settings)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}body{line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1;color:color-mix(in oklab,currentColor 50%,transparent)}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.comm\:absolute{position:absolute!important}.comm\:relative{position:relative!important}.comm\:sticky{position:sticky!important}.comm\:top-4{top:calc(var(--comm-spacing)*4)!important}.comm\:bottom-full{bottom:100%!important}.comm\:z-10{z-index:10!important}.comm\:mt-0\.5{margin-top:calc(var(--comm-spacing)*.5)!important}.comm\:mt-1{margin-top:calc(var(--comm-spacing)*1)!important}.comm\:mt-2{margin-top:calc(var(--comm-spacing)*2)!important}.comm\:mt-3{margin-top:calc(var(--comm-spacing)*3)!important}.comm\:mb-2{margin-bottom:calc(var(--comm-spacing)*2)!important}.comm\:mb-3{margin-bottom:calc(var(--comm-spacing)*3)!important}.comm\:ml-1{margin-left:calc(var(--comm-spacing)*1)!important}.comm\:ml-2{margin-left:calc(var(--comm-spacing)*2)!important}.comm\:flex{display:flex!important}.comm\:hidden{display:none!important}.comm\:inline-block{display:inline-block!important}.comm\:inline-flex{display:inline-flex!important}.comm\:h-3{height:calc(var(--comm-spacing)*3)!important}.comm\:h-4{height:calc(var(--comm-spacing)*4)!important}.comm\:h-8{height:calc(var(--comm-spacing)*8)!important}.comm\:h-10{height:calc(var(--comm-spacing)*10)!important}.comm\:h-full{height:100%!important}.comm\:w-3{width:calc(var(--comm-spacing)*3)!important}.comm\:w-4{width:calc(var(--comm-spacing)*4)!important}.comm\:w-8{width:calc(var(--comm-spacing)*8)!important}.comm\:w-10{width:calc(var(--comm-spacing)*10)!important}.comm\:w-48{width:calc(var(--comm-spacing)*48)!important}.comm\:w-full{width:100%!important}.comm\:w-max{width:max-content!important}.comm\:max-w-xs{max-width:var(--comm-container-xs)!important}.comm\:min-w-full{min-width:100%!important}.comm\:flex-1{flex:1!important}.comm\:flex-shrink-0{flex-shrink:0!important}.comm\:flex-col{flex-direction:column!important}.comm\:flex-wrap{flex-wrap:wrap!important}.comm\:items-center{align-items:center!important}.comm\:items-start{align-items:flex-start!important}.comm\:justify-between{justify-content:space-between!important}.comm\:justify-center{justify-content:center!important}.comm\:justify-end{justify-content:flex-end!important}.comm\:gap-1{gap:calc(var(--comm-spacing)*1)!important}.comm\:gap-2{gap:calc(var(--comm-spacing)*2)!important}.comm\:gap-4{gap:calc(var(--comm-spacing)*4)!important}.comm\:gap-x-1{column-gap:calc(var(--comm-spacing)*1)!important}.comm\:gap-x-2{column-gap:calc(var(--comm-spacing)*2)!important}.comm\:gap-x-4{column-gap:calc(var(--comm-spacing)*4)!important}:where(.comm\:space-y-1>:not(:last-child)){--tw-space-y-reverse:0!important;margin-block-start:calc(calc(var(--comm-spacing)*1)*var(--tw-space-y-reverse))!important;margin-block-end:calc(calc(var(--comm-spacing)*1)*calc(1 - var(--tw-space-y-reverse)))!important}:where(.comm\:space-y-2>:not(:last-child)){--tw-space-y-reverse:0!important;margin-block-start:calc(calc(var(--comm-spacing)*2)*var(--tw-space-y-reverse))!important;margin-block-end:calc(calc(var(--comm-spacing)*2)*calc(1 - var(--tw-space-y-reverse)))!important}:where(.comm\:space-y-6>:not(:last-child)){--tw-space-y-reverse:0!important;margin-block-start:calc(calc(var(--comm-spacing)*6)*var(--tw-space-y-reverse))!important;margin-block-end:calc(calc(var(--comm-spacing)*6)*calc(1 - var(--tw-space-y-reverse)))!important}.comm\:gap-y-2{row-gap:calc(var(--comm-spacing)*2)!important}.comm\:truncate{text-overflow:ellipsis!important;white-space:nowrap!important;overflow:hidden!important}.comm\:rounded-full{border-radius:3.40282e38px!important}.comm\:rounded-lg{border-radius:var(--comm-radius-lg)!important}.comm\:rounded-md{border-radius:var(--comm-radius-md)!important}.comm\:border{border-style:var(--tw-border-style)!important;border-width:1px!important}.comm\:border-t{border-top-style:var(--tw-border-style)!important;border-top-width:1px!important}.comm\:border-l{border-left-style:var(--tw-border-style)!important;border-left-width:1px!important}.comm\:border-dashed{--tw-border-style:dashed!important;border-style:dashed!important}.comm\:border-gray-200{border-color:var(--comm-color-gray-200)!important}.comm\:border-gray-300{border-color:var(--comm-color-gray-300)!important}.comm\:bg-blue-100{background-color:var(--comm-color-blue-100)!important}.comm\:bg-gray-50{background-color:var(--comm-color-gray-50)!important}.comm\:bg-gray-100{background-color:var(--comm-color-gray-100)!important}.comm\:bg-gray-300{background-color:var(--comm-color-gray-300)!important}.comm\:bg-white{background-color:var(--comm-color-white)!important}.comm\:object-cover{object-fit:cover!important}.comm\:object-center{object-position:center!important}.comm\:p-1{padding:calc(var(--comm-spacing)*1)!important}.comm\:p-2{padding:calc(var(--comm-spacing)*2)!important}.comm\:p-4{padding:calc(var(--comm-spacing)*4)!important}.comm\:p-6{padding:calc(var(--comm-spacing)*6)!important}.comm\:px-1\.5{padding-inline:calc(var(--comm-spacing)*1.5)!important}.comm\:px-2{padding-inline:calc(var(--comm-spacing)*2)!important}.comm\:py-0\.5{padding-block:calc(var(--comm-spacing)*.5)!important}.comm\:py-4{padding-block:calc(var(--comm-spacing)*4)!important}.comm\:pt-2{padding-top:calc(var(--comm-spacing)*2)!important}.comm\:pt-3{padding-top:calc(var(--comm-spacing)*3)!important}.comm\:pl-2{padding-left:calc(var(--comm-spacing)*2)!important}.comm\:pl-3{padding-left:calc(var(--comm-spacing)*3)!important}.comm\:pl-6{padding-left:calc(var(--comm-spacing)*6)!important}.comm\:text-center{text-align:center!important}.comm\:text-sm{font-size:var(--comm-text-sm)!important;line-height:var(--tw-leading,var(--comm-text-sm--line-height))!important}.comm\:text-xs{font-size:var(--comm-text-xs)!important;line-height:var(--tw-leading,var(--comm-text-xs--line-height))!important}.comm\:font-bold{--tw-font-weight:var(--comm-font-weight-bold)!important;font-weight:var(--comm-font-weight-bold)!important}.comm\:font-medium{--tw-font-weight:var(--comm-font-weight-medium)!important;font-weight:var(--comm-font-weight-medium)!important}.comm\:whitespace-nowrap{white-space:nowrap!important}.comm\:text-gray-300{color:var(--comm-color-gray-300)!important}.comm\:text-gray-400{color:var(--comm-color-gray-400)!important}.comm\:text-gray-500{color:var(--comm-color-gray-500)!important}.comm\:text-gray-600{color:var(--comm-color-gray-600)!important}.comm\:text-gray-700{color:var(--comm-color-gray-700)!important}.comm\:text-gray-800{color:var(--comm-color-gray-800)!important}.comm\:text-gray-900{color:var(--comm-color-gray-900)!important}.comm\:shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a)!important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important}.comm\:shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a)!important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important}.comm\:transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter!important;transition-timing-function:var(--tw-ease,var(--comm-default-transition-timing-function))!important;transition-duration:var(--tw-duration,var(--comm-default-transition-duration))!important}@media (hover:hover){.comm\:hover\:bg-gray-100:hover{background-color:var(--comm-color-gray-100)!important}.comm\:hover\:bg-gray-200:hover{background-color:var(--comm-color-gray-200)!important}}.comm\:focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentColor)!important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important}.comm\:focus\:ring-offset-2:focus{--tw-ring-offset-width:2px!important;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)!important}.comm\:focus\:outline-none:focus{--tw-outline-style:none!important;outline-style:none!important}.comm\:disabled\:cursor-not-allowed:disabled{cursor:not-allowed!important}.comm\:disabled\:opacity-50:disabled{opacity:.5!important}.comm\:dark\:border-gray-600:where(.dark,.dark *){border-color:var(--comm-color-gray-600)!important}.comm\:dark\:border-gray-700:where(.dark,.dark *){border-color:var(--comm-color-gray-700)!important}.comm\:dark\:bg-gray-600:where(.dark,.dark *){background-color:var(--comm-color-gray-600)!important}.comm\:dark\:bg-gray-800:where(.dark,.dark *){background-color:var(--comm-color-gray-800)!important}.comm\:dark\:bg-gray-900:where(.dark,.dark *){background-color:var(--comm-color-gray-900)!important}.comm\:dark\:text-gray-100:where(.dark,.dark *){color:var(--comm-color-gray-100)!important}.comm\:dark\:text-gray-200:where(.dark,.dark *){color:var(--comm-color-gray-200)!important}.comm\:dark\:text-gray-300:where(.dark,.dark *){color:var(--comm-color-gray-300)!important}.comm\:dark\:text-gray-400:where(.dark,.dark *){color:var(--comm-color-gray-400)!important}.comm\:dark\:text-gray-500:where(.dark,.dark *){color:var(--comm-color-gray-500)!important}@media (hover:hover){.comm\:dark\:hover\:bg-gray-600:where(.dark,.dark *):hover{background-color:var(--comm-color-gray-600)!important}.comm\:dark\:hover\:bg-gray-700:where(.dark,.dark *):hover{background-color:var(--comm-color-gray-700)!important}}}[x-cloak]{display:none}.tiptap{font-size:var(--comm-text-sm)!important;line-height:var(--tw-leading,var(--comm-text-sm--line-height))!important;--tw-leading:var(--comm-leading-normal)!important;line-height:var(--comm-leading-normal)!important}.tiptap p.is-editor-empty:before{color:#adb5bd;content:attr(data-placeholder);float:inline-start;pointer-events:none;height:0}.tiptap .mention{background-color:var(--comm-color-gray-200)!important;padding-inline:calc(var(--comm-spacing)*1)!important;padding-block:calc(var(--comm-spacing)*.5)!important;--tw-font-weight:var(--comm-font-weight-bold)!important;font-weight:var(--comm-font-weight-bold)!important;color:var(--comm-color-blue-500)!important;border-radius:.25rem!important;display:inline-block!important}.mention-suggestion{z-index:1000;background:#fff;border:1px solid #ddd;border-radius:5px;max-height:150px;padding:5px;overflow-y:auto}.mention-item{cursor:pointer;padding:5px 10px}.mention-item:hover{background-color:var(--comm-color-gray-100)!important}@keyframes spin{to{transform:rotate(360deg)}}@keyframes ping{75%,to{opacity:0;transform:scale(2)}}@keyframes pulse{50%{opacity:.5}}@keyframes bounce{0%,to{animation-timing-function:cubic-bezier(.8,0,1,1);transform:translateY(-25%)}50%{animation-timing-function:cubic-bezier(0,0,.2,1);transform:none}}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-leading{syntax:"*";inherits:false} \ No newline at end of file +@layer theme{:root,:host{--comm-font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--comm-font-serif:ui-serif,Georgia,Cambria,"Times New Roman",Times,serif;--comm-font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--comm-color-red-50:oklch(.971 .013 17.38);--comm-color-red-100:oklch(.936 .032 17.717);--comm-color-red-200:oklch(.885 .062 18.334);--comm-color-red-300:oklch(.808 .114 19.571);--comm-color-red-400:oklch(.704 .191 22.216);--comm-color-red-500:oklch(.637 .237 25.331);--comm-color-red-600:oklch(.577 .245 27.325);--comm-color-red-700:oklch(.505 .213 27.518);--comm-color-red-800:oklch(.444 .177 26.899);--comm-color-red-900:oklch(.396 .141 25.723);--comm-color-red-950:oklch(.258 .092 26.042);--comm-color-orange-50:oklch(.98 .016 73.684);--comm-color-orange-100:oklch(.954 .038 75.164);--comm-color-orange-200:oklch(.901 .076 70.697);--comm-color-orange-300:oklch(.837 .128 66.29);--comm-color-orange-400:oklch(.75 .183 55.934);--comm-color-orange-500:oklch(.705 .213 47.604);--comm-color-orange-600:oklch(.646 .222 41.116);--comm-color-orange-700:oklch(.553 .195 38.402);--comm-color-orange-800:oklch(.47 .157 37.304);--comm-color-orange-900:oklch(.408 .123 38.172);--comm-color-orange-950:oklch(.266 .079 36.259);--comm-color-amber-50:oklch(.987 .022 95.277);--comm-color-amber-100:oklch(.962 .059 95.617);--comm-color-amber-200:oklch(.924 .12 95.746);--comm-color-amber-300:oklch(.879 .169 91.605);--comm-color-amber-400:oklch(.828 .189 84.429);--comm-color-amber-500:oklch(.769 .188 70.08);--comm-color-amber-600:oklch(.666 .179 58.318);--comm-color-amber-700:oklch(.555 .163 48.998);--comm-color-amber-800:oklch(.473 .137 46.201);--comm-color-amber-900:oklch(.414 .112 45.904);--comm-color-amber-950:oklch(.279 .077 45.635);--comm-color-yellow-50:oklch(.987 .026 102.212);--comm-color-yellow-100:oklch(.973 .071 103.193);--comm-color-yellow-200:oklch(.945 .129 101.54);--comm-color-yellow-300:oklch(.905 .182 98.111);--comm-color-yellow-400:oklch(.852 .199 91.936);--comm-color-yellow-500:oklch(.795 .184 86.047);--comm-color-yellow-600:oklch(.681 .162 75.834);--comm-color-yellow-700:oklch(.554 .135 66.442);--comm-color-yellow-800:oklch(.476 .114 61.907);--comm-color-yellow-900:oklch(.421 .095 57.708);--comm-color-yellow-950:oklch(.286 .066 53.813);--comm-color-lime-50:oklch(.986 .031 120.757);--comm-color-lime-100:oklch(.967 .067 122.328);--comm-color-lime-200:oklch(.938 .127 124.321);--comm-color-lime-300:oklch(.897 .196 126.665);--comm-color-lime-400:oklch(.841 .238 128.85);--comm-color-lime-500:oklch(.768 .233 130.85);--comm-color-lime-600:oklch(.648 .2 131.684);--comm-color-lime-700:oklch(.532 .157 131.589);--comm-color-lime-800:oklch(.453 .124 130.933);--comm-color-lime-900:oklch(.405 .101 131.063);--comm-color-lime-950:oklch(.274 .072 132.109);--comm-color-green-50:oklch(.982 .018 155.826);--comm-color-green-100:oklch(.962 .044 156.743);--comm-color-green-200:oklch(.925 .084 155.995);--comm-color-green-300:oklch(.871 .15 154.449);--comm-color-green-400:oklch(.792 .209 151.711);--comm-color-green-500:oklch(.723 .219 149.579);--comm-color-green-600:oklch(.627 .194 149.214);--comm-color-green-700:oklch(.527 .154 150.069);--comm-color-green-800:oklch(.448 .119 151.328);--comm-color-green-900:oklch(.393 .095 152.535);--comm-color-green-950:oklch(.266 .065 152.934);--comm-color-emerald-50:oklch(.979 .021 166.113);--comm-color-emerald-100:oklch(.95 .052 163.051);--comm-color-emerald-200:oklch(.905 .093 164.15);--comm-color-emerald-300:oklch(.845 .143 164.978);--comm-color-emerald-400:oklch(.765 .177 163.223);--comm-color-emerald-500:oklch(.696 .17 162.48);--comm-color-emerald-600:oklch(.596 .145 163.225);--comm-color-emerald-700:oklch(.508 .118 165.612);--comm-color-emerald-800:oklch(.432 .095 166.913);--comm-color-emerald-900:oklch(.378 .077 168.94);--comm-color-emerald-950:oklch(.262 .051 172.552);--comm-color-teal-50:oklch(.984 .014 180.72);--comm-color-teal-100:oklch(.953 .051 180.801);--comm-color-teal-200:oklch(.91 .096 180.426);--comm-color-teal-300:oklch(.855 .138 181.071);--comm-color-teal-400:oklch(.777 .152 181.912);--comm-color-teal-500:oklch(.704 .14 182.503);--comm-color-teal-600:oklch(.6 .118 184.704);--comm-color-teal-700:oklch(.511 .096 186.391);--comm-color-teal-800:oklch(.437 .078 188.216);--comm-color-teal-900:oklch(.386 .063 188.416);--comm-color-teal-950:oklch(.277 .046 192.524);--comm-color-cyan-50:oklch(.984 .019 200.873);--comm-color-cyan-100:oklch(.956 .045 203.388);--comm-color-cyan-200:oklch(.917 .08 205.041);--comm-color-cyan-300:oklch(.865 .127 207.078);--comm-color-cyan-400:oklch(.789 .154 211.53);--comm-color-cyan-500:oklch(.715 .143 215.221);--comm-color-cyan-600:oklch(.609 .126 221.723);--comm-color-cyan-700:oklch(.52 .105 223.128);--comm-color-cyan-800:oklch(.45 .085 224.283);--comm-color-cyan-900:oklch(.398 .07 227.392);--comm-color-cyan-950:oklch(.302 .056 229.695);--comm-color-sky-50:oklch(.977 .013 236.62);--comm-color-sky-100:oklch(.951 .026 236.824);--comm-color-sky-200:oklch(.901 .058 230.902);--comm-color-sky-300:oklch(.828 .111 230.318);--comm-color-sky-400:oklch(.746 .16 232.661);--comm-color-sky-500:oklch(.685 .169 237.323);--comm-color-sky-600:oklch(.588 .158 241.966);--comm-color-sky-700:oklch(.5 .134 242.749);--comm-color-sky-800:oklch(.443 .11 240.79);--comm-color-sky-900:oklch(.391 .09 240.876);--comm-color-sky-950:oklch(.293 .066 243.157);--comm-color-blue-50:oklch(.97 .014 254.604);--comm-color-blue-100:oklch(.932 .032 255.585);--comm-color-blue-200:oklch(.882 .059 254.128);--comm-color-blue-300:oklch(.809 .105 251.813);--comm-color-blue-400:oklch(.707 .165 254.624);--comm-color-blue-500:oklch(.623 .214 259.815);--comm-color-blue-600:oklch(.546 .245 262.881);--comm-color-blue-700:oklch(.488 .243 264.376);--comm-color-blue-800:oklch(.424 .199 265.638);--comm-color-blue-900:oklch(.379 .146 265.522);--comm-color-blue-950:oklch(.282 .091 267.935);--comm-color-indigo-50:oklch(.962 .018 272.314);--comm-color-indigo-100:oklch(.93 .034 272.788);--comm-color-indigo-200:oklch(.87 .065 274.039);--comm-color-indigo-300:oklch(.785 .115 274.713);--comm-color-indigo-400:oklch(.673 .182 276.935);--comm-color-indigo-500:oklch(.585 .233 277.117);--comm-color-indigo-600:oklch(.511 .262 276.966);--comm-color-indigo-700:oklch(.457 .24 277.023);--comm-color-indigo-800:oklch(.398 .195 277.366);--comm-color-indigo-900:oklch(.359 .144 278.697);--comm-color-indigo-950:oklch(.257 .09 281.288);--comm-color-violet-50:oklch(.969 .016 293.756);--comm-color-violet-100:oklch(.943 .029 294.588);--comm-color-violet-200:oklch(.894 .057 293.283);--comm-color-violet-300:oklch(.811 .111 293.571);--comm-color-violet-400:oklch(.702 .183 293.541);--comm-color-violet-500:oklch(.606 .25 292.717);--comm-color-violet-600:oklch(.541 .281 293.009);--comm-color-violet-700:oklch(.491 .27 292.581);--comm-color-violet-800:oklch(.432 .232 292.759);--comm-color-violet-900:oklch(.38 .189 293.745);--comm-color-violet-950:oklch(.283 .141 291.089);--comm-color-purple-50:oklch(.977 .014 308.299);--comm-color-purple-100:oklch(.946 .033 307.174);--comm-color-purple-200:oklch(.902 .063 306.703);--comm-color-purple-300:oklch(.827 .119 306.383);--comm-color-purple-400:oklch(.714 .203 305.504);--comm-color-purple-500:oklch(.627 .265 303.9);--comm-color-purple-600:oklch(.558 .288 302.321);--comm-color-purple-700:oklch(.496 .265 301.924);--comm-color-purple-800:oklch(.438 .218 303.724);--comm-color-purple-900:oklch(.381 .176 304.987);--comm-color-purple-950:oklch(.291 .149 302.717);--comm-color-fuchsia-50:oklch(.977 .017 320.058);--comm-color-fuchsia-100:oklch(.952 .037 318.852);--comm-color-fuchsia-200:oklch(.903 .076 319.62);--comm-color-fuchsia-300:oklch(.833 .145 321.434);--comm-color-fuchsia-400:oklch(.74 .238 322.16);--comm-color-fuchsia-500:oklch(.667 .295 322.15);--comm-color-fuchsia-600:oklch(.591 .293 322.896);--comm-color-fuchsia-700:oklch(.518 .253 323.949);--comm-color-fuchsia-800:oklch(.452 .211 324.591);--comm-color-fuchsia-900:oklch(.401 .17 325.612);--comm-color-fuchsia-950:oklch(.293 .136 325.661);--comm-color-pink-50:oklch(.971 .014 343.198);--comm-color-pink-100:oklch(.948 .028 342.258);--comm-color-pink-200:oklch(.899 .061 343.231);--comm-color-pink-300:oklch(.823 .12 346.018);--comm-color-pink-400:oklch(.718 .202 349.761);--comm-color-pink-500:oklch(.656 .241 354.308);--comm-color-pink-600:oklch(.592 .249 .584);--comm-color-pink-700:oklch(.525 .223 3.958);--comm-color-pink-800:oklch(.459 .187 3.815);--comm-color-pink-900:oklch(.408 .153 2.432);--comm-color-pink-950:oklch(.284 .109 3.907);--comm-color-rose-50:oklch(.969 .015 12.422);--comm-color-rose-100:oklch(.941 .03 12.58);--comm-color-rose-200:oklch(.892 .058 10.001);--comm-color-rose-300:oklch(.81 .117 11.638);--comm-color-rose-400:oklch(.712 .194 13.428);--comm-color-rose-500:oklch(.645 .246 16.439);--comm-color-rose-600:oklch(.586 .253 17.585);--comm-color-rose-700:oklch(.514 .222 16.935);--comm-color-rose-800:oklch(.455 .188 13.697);--comm-color-rose-900:oklch(.41 .159 10.272);--comm-color-rose-950:oklch(.271 .105 12.094);--comm-color-slate-50:oklch(.984 .003 247.858);--comm-color-slate-100:oklch(.968 .007 247.896);--comm-color-slate-200:oklch(.929 .013 255.508);--comm-color-slate-300:oklch(.869 .022 252.894);--comm-color-slate-400:oklch(.704 .04 256.788);--comm-color-slate-500:oklch(.554 .046 257.417);--comm-color-slate-600:oklch(.446 .043 257.281);--comm-color-slate-700:oklch(.372 .044 257.287);--comm-color-slate-800:oklch(.279 .041 260.031);--comm-color-slate-900:oklch(.208 .042 265.755);--comm-color-slate-950:oklch(.129 .042 264.695);--comm-color-gray-50:oklch(.985 .002 247.839);--comm-color-gray-100:oklch(.967 .003 264.542);--comm-color-gray-200:oklch(.928 .006 264.531);--comm-color-gray-300:oklch(.872 .01 258.338);--comm-color-gray-400:oklch(.707 .022 261.325);--comm-color-gray-500:oklch(.551 .027 264.364);--comm-color-gray-600:oklch(.446 .03 256.802);--comm-color-gray-700:oklch(.373 .034 259.733);--comm-color-gray-800:oklch(.278 .033 256.848);--comm-color-gray-900:oklch(.21 .034 264.665);--comm-color-gray-950:oklch(.13 .028 261.692);--comm-color-zinc-50:oklch(.985 0 0);--comm-color-zinc-100:oklch(.967 .001 286.375);--comm-color-zinc-200:oklch(.92 .004 286.32);--comm-color-zinc-300:oklch(.871 .006 286.286);--comm-color-zinc-400:oklch(.705 .015 286.067);--comm-color-zinc-500:oklch(.552 .016 285.938);--comm-color-zinc-600:oklch(.442 .017 285.786);--comm-color-zinc-700:oklch(.37 .013 285.805);--comm-color-zinc-800:oklch(.274 .006 286.033);--comm-color-zinc-900:oklch(.21 .006 285.885);--comm-color-zinc-950:oklch(.141 .005 285.823);--comm-color-neutral-50:oklch(.985 0 0);--comm-color-neutral-100:oklch(.97 0 0);--comm-color-neutral-200:oklch(.922 0 0);--comm-color-neutral-300:oklch(.87 0 0);--comm-color-neutral-400:oklch(.708 0 0);--comm-color-neutral-500:oklch(.556 0 0);--comm-color-neutral-600:oklch(.439 0 0);--comm-color-neutral-700:oklch(.371 0 0);--comm-color-neutral-800:oklch(.269 0 0);--comm-color-neutral-900:oklch(.205 0 0);--comm-color-neutral-950:oklch(.145 0 0);--comm-color-stone-50:oklch(.985 .001 106.423);--comm-color-stone-100:oklch(.97 .001 106.424);--comm-color-stone-200:oklch(.923 .003 48.717);--comm-color-stone-300:oklch(.869 .005 56.366);--comm-color-stone-400:oklch(.709 .01 56.259);--comm-color-stone-500:oklch(.553 .013 58.071);--comm-color-stone-600:oklch(.444 .011 73.639);--comm-color-stone-700:oklch(.374 .01 67.558);--comm-color-stone-800:oklch(.268 .007 34.298);--comm-color-stone-900:oklch(.216 .006 56.043);--comm-color-stone-950:oklch(.147 .004 49.25);--comm-color-black:#000;--comm-color-white:#fff;--comm-spacing:.25rem;--comm-breakpoint-sm:40rem;--comm-breakpoint-md:48rem;--comm-breakpoint-lg:64rem;--comm-breakpoint-xl:80rem;--comm-breakpoint-2xl:96rem;--comm-container-3xs:16rem;--comm-container-2xs:18rem;--comm-container-xs:20rem;--comm-container-sm:24rem;--comm-container-md:28rem;--comm-container-lg:32rem;--comm-container-xl:36rem;--comm-container-2xl:42rem;--comm-container-3xl:48rem;--comm-container-4xl:56rem;--comm-container-5xl:64rem;--comm-container-6xl:72rem;--comm-container-7xl:80rem;--comm-text-xs:.75rem;--comm-text-xs--line-height:calc(1/.75);--comm-text-sm:.875rem;--comm-text-sm--line-height:calc(1.25/.875);--comm-text-base:1rem;--comm-text-base--line-height:calc(1.5/1);--comm-text-lg:1.125rem;--comm-text-lg--line-height:calc(1.75/1.125);--comm-text-xl:1.25rem;--comm-text-xl--line-height:calc(1.75/1.25);--comm-text-2xl:1.5rem;--comm-text-2xl--line-height:calc(2/1.5);--comm-text-3xl:1.875rem;--comm-text-3xl--line-height:calc(2.25/1.875);--comm-text-4xl:2.25rem;--comm-text-4xl--line-height:calc(2.5/2.25);--comm-text-5xl:3rem;--comm-text-5xl--line-height:1;--comm-text-6xl:3.75rem;--comm-text-6xl--line-height:1;--comm-text-7xl:4.5rem;--comm-text-7xl--line-height:1;--comm-text-8xl:6rem;--comm-text-8xl--line-height:1;--comm-text-9xl:8rem;--comm-text-9xl--line-height:1;--comm-font-weight-thin:100;--comm-font-weight-extralight:200;--comm-font-weight-light:300;--comm-font-weight-normal:400;--comm-font-weight-medium:500;--comm-font-weight-semibold:600;--comm-font-weight-bold:700;--comm-font-weight-extrabold:800;--comm-font-weight-black:900;--comm-tracking-tighter:-.05em;--comm-tracking-tight:-.025em;--comm-tracking-normal:0em;--comm-tracking-wide:.025em;--comm-tracking-wider:.05em;--comm-tracking-widest:.1em;--comm-leading-tight:1.25;--comm-leading-snug:1.375;--comm-leading-normal:1.5;--comm-leading-relaxed:1.625;--comm-leading-loose:2;--comm-radius-xs:.125rem;--comm-radius-sm:.25rem;--comm-radius-md:.375rem;--comm-radius-lg:.5rem;--comm-radius-xl:.75rem;--comm-radius-2xl:1rem;--comm-radius-3xl:1.5rem;--comm-radius-4xl:2rem;--comm-shadow-2xs:0 1px #0000000d;--comm-shadow-xs:0 1px 2px 0 #0000000d;--comm-shadow-sm:0 1px 3px 0 #0000001a,0 1px 2px -1px #0000001a;--comm-shadow-md:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a;--comm-shadow-lg:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;--comm-shadow-xl:0 20px 25px -5px #0000001a,0 8px 10px -6px #0000001a;--comm-shadow-2xl:0 25px 50px -12px #00000040;--comm-inset-shadow-2xs:inset 0 1px #0000000d;--comm-inset-shadow-xs:inset 0 1px 1px #0000000d;--comm-inset-shadow-sm:inset 0 2px 4px #0000000d;--comm-drop-shadow-xs:0 1px 1px #0000000d;--comm-drop-shadow-sm:0 1px 2px #00000026;--comm-drop-shadow-md:0 3px 3px #0000001f;--comm-drop-shadow-lg:0 4px 4px #00000026;--comm-drop-shadow-xl:0 9px 7px #0000001a;--comm-drop-shadow-2xl:0 25px 25px #00000026;--comm-ease-in:cubic-bezier(.4,0,1,1);--comm-ease-out:cubic-bezier(0,0,.2,1);--comm-ease-in-out:cubic-bezier(.4,0,.2,1);--comm-animate-spin:spin 1s linear infinite;--comm-animate-ping:ping 1s cubic-bezier(0,0,.2,1)infinite;--comm-animate-pulse:pulse 2s cubic-bezier(.4,0,.6,1)infinite;--comm-animate-bounce:bounce 1s infinite;--comm-blur-xs:4px;--comm-blur-sm:8px;--comm-blur-md:12px;--comm-blur-lg:16px;--comm-blur-xl:24px;--comm-blur-2xl:40px;--comm-blur-3xl:64px;--comm-perspective-dramatic:100px;--comm-perspective-near:300px;--comm-perspective-normal:500px;--comm-perspective-midrange:800px;--comm-perspective-distant:1200px;--comm-aspect-video:16/9;--comm-default-transition-duration:.15s;--comm-default-transition-timing-function:cubic-bezier(.4,0,.2,1);--comm-default-font-family:var(--font-sans);--comm-default-font-feature-settings:var(--font-sans--font-feature-settings);--comm-default-font-variation-settings:var(--font-sans--font-variation-settings);--comm-default-mono-font-family:var(--font-mono);--comm-default-mono-font-feature-settings:var(--font-mono--font-feature-settings);--comm-default-mono-font-variation-settings:var(--font-mono--font-variation-settings)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}body{line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1;color:color-mix(in oklab,currentColor 50%,transparent)}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.comm\:absolute{position:absolute!important}.comm\:relative{position:relative!important}.comm\:sticky{position:sticky!important}.comm\:top-4{top:calc(var(--comm-spacing)*4)!important}.comm\:bottom-full{bottom:100%!important}.comm\:z-10{z-index:10!important}.comm\:mt-0\.5{margin-top:calc(var(--comm-spacing)*.5)!important}.comm\:mt-1{margin-top:calc(var(--comm-spacing)*1)!important}.comm\:mt-2{margin-top:calc(var(--comm-spacing)*2)!important}.comm\:mt-3{margin-top:calc(var(--comm-spacing)*3)!important}.comm\:mb-1{margin-bottom:calc(var(--comm-spacing)*1)!important}.comm\:mb-2{margin-bottom:calc(var(--comm-spacing)*2)!important}.comm\:mb-3{margin-bottom:calc(var(--comm-spacing)*3)!important}.comm\:ml-1{margin-left:calc(var(--comm-spacing)*1)!important}.comm\:ml-2{margin-left:calc(var(--comm-spacing)*2)!important}.comm\:flex{display:flex!important}.comm\:hidden{display:none!important}.comm\:inline-block{display:inline-block!important}.comm\:inline-flex{display:inline-flex!important}.comm\:h-3{height:calc(var(--comm-spacing)*3)!important}.comm\:h-4{height:calc(var(--comm-spacing)*4)!important}.comm\:h-7{height:calc(var(--comm-spacing)*7)!important}.comm\:h-8{height:calc(var(--comm-spacing)*8)!important}.comm\:h-10{height:calc(var(--comm-spacing)*10)!important}.comm\:h-full{height:100%!important}.comm\:w-3{width:calc(var(--comm-spacing)*3)!important}.comm\:w-4{width:calc(var(--comm-spacing)*4)!important}.comm\:w-7{width:calc(var(--comm-spacing)*7)!important}.comm\:w-8{width:calc(var(--comm-spacing)*8)!important}.comm\:w-10{width:calc(var(--comm-spacing)*10)!important}.comm\:w-48{width:calc(var(--comm-spacing)*48)!important}.comm\:w-full{width:100%!important}.comm\:w-max{width:max-content!important}.comm\:max-w-xs{max-width:var(--comm-container-xs)!important}.comm\:min-w-full{min-width:100%!important}.comm\:flex-1{flex:1!important}.comm\:flex-shrink-0{flex-shrink:0!important}.comm\:-rotate-90{rotate:-90deg!important}.comm\:flex-col{flex-direction:column!important}.comm\:flex-wrap{flex-wrap:wrap!important}.comm\:items-center{align-items:center!important}.comm\:items-start{align-items:flex-start!important}.comm\:justify-between{justify-content:space-between!important}.comm\:justify-center{justify-content:center!important}.comm\:justify-end{justify-content:flex-end!important}.comm\:gap-1{gap:calc(var(--comm-spacing)*1)!important}.comm\:gap-2{gap:calc(var(--comm-spacing)*2)!important}.comm\:gap-4{gap:calc(var(--comm-spacing)*4)!important}.comm\:gap-x-1{column-gap:calc(var(--comm-spacing)*1)!important}.comm\:gap-x-2{column-gap:calc(var(--comm-spacing)*2)!important}.comm\:gap-x-3{column-gap:calc(var(--comm-spacing)*3)!important}.comm\:gap-x-4{column-gap:calc(var(--comm-spacing)*4)!important}:where(.comm\:space-y-1>:not(:last-child)){--tw-space-y-reverse:0!important;margin-block-start:calc(calc(var(--comm-spacing)*1)*var(--tw-space-y-reverse))!important;margin-block-end:calc(calc(var(--comm-spacing)*1)*calc(1 - var(--tw-space-y-reverse)))!important}:where(.comm\:space-y-2>:not(:last-child)){--tw-space-y-reverse:0!important;margin-block-start:calc(calc(var(--comm-spacing)*2)*var(--tw-space-y-reverse))!important;margin-block-end:calc(calc(var(--comm-spacing)*2)*calc(1 - var(--tw-space-y-reverse)))!important}:where(.comm\:space-y-6>:not(:last-child)){--tw-space-y-reverse:0!important;margin-block-start:calc(calc(var(--comm-spacing)*6)*var(--tw-space-y-reverse))!important;margin-block-end:calc(calc(var(--comm-spacing)*6)*calc(1 - var(--tw-space-y-reverse)))!important}.comm\:gap-y-2{row-gap:calc(var(--comm-spacing)*2)!important}.comm\:truncate{text-overflow:ellipsis!important;white-space:nowrap!important;overflow:hidden!important}.comm\:rounded{border-radius:.25rem!important}.comm\:rounded-full{border-radius:3.40282e38px!important}.comm\:rounded-lg{border-radius:var(--comm-radius-lg)!important}.comm\:rounded-md{border-radius:var(--comm-radius-md)!important}.comm\:border{border-style:var(--tw-border-style)!important;border-width:1px!important}.comm\:border-t{border-top-style:var(--tw-border-style)!important;border-top-width:1px!important}.comm\:border-dashed{--tw-border-style:dashed!important;border-style:dashed!important}.comm\:border-gray-200{border-color:var(--comm-color-gray-200)!important}.comm\:border-gray-300{border-color:var(--comm-color-gray-300)!important}.comm\:bg-blue-100{background-color:var(--comm-color-blue-100)!important}.comm\:bg-gray-50{background-color:var(--comm-color-gray-50)!important}.comm\:bg-gray-100{background-color:var(--comm-color-gray-100)!important}.comm\:bg-gray-300{background-color:var(--comm-color-gray-300)!important}.comm\:bg-white{background-color:var(--comm-color-white)!important}.comm\:object-cover{object-fit:cover!important}.comm\:object-center{object-position:center!important}.comm\:p-1{padding:calc(var(--comm-spacing)*1)!important}.comm\:p-2{padding:calc(var(--comm-spacing)*2)!important}.comm\:p-4{padding:calc(var(--comm-spacing)*4)!important}.comm\:p-6{padding:calc(var(--comm-spacing)*6)!important}.comm\:px-1\.5{padding-inline:calc(var(--comm-spacing)*1.5)!important}.comm\:px-2{padding-inline:calc(var(--comm-spacing)*2)!important}.comm\:py-0\.5{padding-block:calc(var(--comm-spacing)*.5)!important}.comm\:py-2{padding-block:calc(var(--comm-spacing)*2)!important}.comm\:py-4{padding-block:calc(var(--comm-spacing)*4)!important}.comm\:pt-2{padding-top:calc(var(--comm-spacing)*2)!important}.comm\:pt-3{padding-top:calc(var(--comm-spacing)*3)!important}.comm\:pl-2{padding-left:calc(var(--comm-spacing)*2)!important}.comm\:pl-3{padding-left:calc(var(--comm-spacing)*3)!important}.comm\:pl-6{padding-left:calc(var(--comm-spacing)*6)!important}.comm\:text-center{text-align:center!important}.comm\:text-sm{font-size:var(--comm-text-sm)!important;line-height:var(--tw-leading,var(--comm-text-sm--line-height))!important}.comm\:text-xs{font-size:var(--comm-text-xs)!important;line-height:var(--tw-leading,var(--comm-text-xs--line-height))!important}.comm\:font-bold{--tw-font-weight:var(--comm-font-weight-bold)!important;font-weight:var(--comm-font-weight-bold)!important}.comm\:font-medium{--tw-font-weight:var(--comm-font-weight-medium)!important;font-weight:var(--comm-font-weight-medium)!important}.comm\:whitespace-nowrap{white-space:nowrap!important}.comm\:text-gray-300{color:var(--comm-color-gray-300)!important}.comm\:text-gray-400{color:var(--comm-color-gray-400)!important}.comm\:text-gray-500{color:var(--comm-color-gray-500)!important}.comm\:text-gray-600{color:var(--comm-color-gray-600)!important}.comm\:text-gray-700{color:var(--comm-color-gray-700)!important}.comm\:text-gray-800{color:var(--comm-color-gray-800)!important}.comm\:text-gray-900{color:var(--comm-color-gray-900)!important}.comm\:shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a)!important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important}.comm\:shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a)!important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important}.comm\:transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter!important;transition-timing-function:var(--tw-ease,var(--comm-default-transition-timing-function))!important;transition-duration:var(--tw-duration,var(--comm-default-transition-duration))!important}.comm\:transition-transform{transition-property:transform,translate,scale,rotate!important;transition-timing-function:var(--tw-ease,var(--comm-default-transition-timing-function))!important;transition-duration:var(--tw-duration,var(--comm-default-transition-duration))!important}@media (hover:hover){.comm\:hover\:bg-gray-100:hover{background-color:var(--comm-color-gray-100)!important}.comm\:hover\:bg-gray-200:hover{background-color:var(--comm-color-gray-200)!important}.comm\:hover\:text-gray-700:hover{color:var(--comm-color-gray-700)!important}}.comm\:focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentColor)!important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important}.comm\:focus\:ring-offset-2:focus{--tw-ring-offset-width:2px!important;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)!important}.comm\:focus\:outline-none:focus{--tw-outline-style:none!important;outline-style:none!important}.comm\:focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentColor)!important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important}.comm\:focus-visible\:ring-blue-500:focus-visible{--tw-ring-color:var(--comm-color-blue-500)!important}.comm\:disabled\:cursor-not-allowed:disabled{cursor:not-allowed!important}.comm\:disabled\:opacity-50:disabled{opacity:.5!important}.comm\:dark\:border-gray-600:where(.dark,.dark *){border-color:var(--comm-color-gray-600)!important}.comm\:dark\:border-gray-700:where(.dark,.dark *){border-color:var(--comm-color-gray-700)!important}.comm\:dark\:bg-gray-600:where(.dark,.dark *){background-color:var(--comm-color-gray-600)!important}.comm\:dark\:bg-gray-800:where(.dark,.dark *){background-color:var(--comm-color-gray-800)!important}.comm\:dark\:bg-gray-900:where(.dark,.dark *){background-color:var(--comm-color-gray-900)!important}.comm\:dark\:text-gray-100:where(.dark,.dark *){color:var(--comm-color-gray-100)!important}.comm\:dark\:text-gray-200:where(.dark,.dark *){color:var(--comm-color-gray-200)!important}.comm\:dark\:text-gray-300:where(.dark,.dark *){color:var(--comm-color-gray-300)!important}.comm\:dark\:text-gray-400:where(.dark,.dark *){color:var(--comm-color-gray-400)!important}.comm\:dark\:text-gray-500:where(.dark,.dark *){color:var(--comm-color-gray-500)!important}@media (hover:hover){.comm\:dark\:hover\:bg-gray-600:where(.dark,.dark *):hover{background-color:var(--comm-color-gray-600)!important}.comm\:dark\:hover\:bg-gray-700:where(.dark,.dark *):hover{background-color:var(--comm-color-gray-700)!important}.comm\:dark\:hover\:text-gray-200:where(.dark,.dark *):hover{color:var(--comm-color-gray-200)!important}}}[x-cloak]{display:none}.tiptap{font-size:var(--comm-text-sm)!important;line-height:var(--tw-leading,var(--comm-text-sm--line-height))!important;--tw-leading:var(--comm-leading-normal)!important;line-height:var(--comm-leading-normal)!important}.tiptap p.is-editor-empty:before{color:#adb5bd;content:attr(data-placeholder);float:inline-start;pointer-events:none;height:0}.tiptap .mention{background-color:var(--comm-color-gray-200)!important;padding-inline:calc(var(--comm-spacing)*1)!important;padding-block:calc(var(--comm-spacing)*.5)!important;--tw-font-weight:var(--comm-font-weight-bold)!important;font-weight:var(--comm-font-weight-bold)!important;color:var(--comm-color-blue-500)!important;border-radius:.25rem!important;display:inline-block!important}.mention-suggestion{z-index:1000;background:#fff;border:1px solid #ddd;border-radius:5px;max-height:150px;padding:5px;overflow-y:auto}.mention-item{cursor:pointer;padding:5px 10px}.mention-item:hover{background-color:var(--comm-color-gray-100)!important}.commentions-thread{pointer-events:none;width:1.5rem;position:absolute;inset:0 auto 0 0}.commentions-thread:before,.commentions-thread:after{content:"";position:absolute;left:.5rem}.commentions-thread:before{background-color:#d1d5db;width:2px;top:0;bottom:0}.commentions-thread:after{border-bottom:2px solid #d1d5db;border-left:2px solid #d1d5db;border-bottom-left-radius:.75rem;width:1rem;height:1.5rem;top:0}.commentions-replies>:last-child .commentions-thread:before{height:1.5rem;bottom:auto}:where(.dark,.dark *) .commentions-thread:before{background-color:#4b5563}:where(.dark,.dark *) .commentions-thread:after{border-color:#4b5563}@keyframes spin{to{transform:rotate(360deg)}}@keyframes ping{75%,to{opacity:0;transform:scale(2)}}@keyframes pulse{50%{opacity:.5}}@keyframes bounce{0%,to{animation-timing-function:cubic-bezier(.8,0,1,1);transform:translateY(-25%)}50%{animation-timing-function:cubic-bezier(0,0,.2,1);transform:none}}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-leading{syntax:"*";inherits:false} \ No newline at end of file diff --git a/resources/lang/en/comments.php b/resources/lang/en/comments.php index cee9cb2..8bed81b 100644 --- a/resources/lang/en/comments.php +++ b/resources/lang/en/comments.php @@ -17,6 +17,8 @@ 'cancel' => 'Cancel', 'delete' => 'Delete', 'reply' => 'Reply', + 'replies_count' => '{0} No replies|{1} :count reply|[2,*] :count replies', + 'hide_replies' => 'Hide replies', 'save' => 'Save', 'comment' => 'Comment', 'add_reaction' => 'Add Reaction', diff --git a/resources/views/comment.blade.php b/resources/views/comment.blade.php index 7db7ef3..d80b535 100644 --- a/resources/views/comment.blade.php +++ b/resources/views/comment.blade.php @@ -1,14 +1,33 @@ @use('\Kirschbaum\Commentions\Config') -
+
$depth === 0, + 'comm:relative comm:gap-x-3 comm:py-2 comm:pl-6' => $depth > 0, + ]) + id="filament-comment-{{ $comment->getId() }}" +> + @if ($depth > 0) + + @endif + @if ($avatar = $comment->getAuthorAvatar()) {{ __('commentions::comments.user_avatar_alt') }} $depth === 0, + 'comm:w-7 comm:h-7' => $depth > 0, + ]) /> @else -
+
$depth === 0, + 'comm:w-7 comm:h-7' => $depth > 0, + ])>
@endif
@@ -155,17 +174,45 @@ class="comm:text-xs comm:text-gray-300 comm:ml-1" @endif @if ($comment->isComment() && config('commentions.threading.enabled', false) && $comment->replies->isNotEmpty()) -
- @foreach ($comment->replies as $reply) - + + +
$this->shouldIndentReplies(), + ]) + > + @foreach ($comment->replies as $reply) + + @endforeach +
@endif @endif diff --git a/src/Comment.php b/src/Comment.php index 7ca68de..5af5d0d 100644 --- a/src/Comment.php +++ b/src/Comment.php @@ -196,6 +196,17 @@ public function depth(): int return $depth; } + /** + * Total number of descendant comments across all nested reply levels. + */ + public function repliesCount(): int + { + return $this->replies->reduce( + fn (int $carry, self $reply): int => $carry + 1 + $reply->repliesCount(), + 0, + ); + } + public function toggleReaction(string $reaction): void { ToggleCommentReaction::run($this, $reaction, Config::resolveAuthenticatedUser()); diff --git a/src/Livewire/Comment.php b/src/Livewire/Comment.php index ac89ee9..7a08f1d 100644 --- a/src/Livewire/Comment.php +++ b/src/Livewire/Comment.php @@ -17,6 +17,13 @@ class Comment extends Component { use HasMentions; + /** + * Deepest level that still receives added horizontal indent. Beyond this + * the thread line still renders, but no extra padding is added so deep + * threads don't compound horizontally on small screens. + */ + public const INDENT_CAP_DEPTH = 2; + public CommentModel|RenderableComment $comment; public string $commentBody = ''; @@ -189,6 +196,15 @@ public function canReply(): bool && (bool) Config::resolveAuthenticatedUser()?->can('create', Config::getCommentModel()); } + /** + * Whether the replies wrapper rendered by this comment should add + * horizontal indent. Past the cap the thread line still renders. + */ + public function shouldIndentReplies(): bool + { + return $this->depth < self::INDENT_CAP_DEPTH; + } + protected function maxReplyDepth(): int { return max(0, (int) config('commentions.threading.max_depth', 3)); diff --git a/tests/Livewire/CommentThreadingTest.php b/tests/Livewire/CommentThreadingTest.php index c703988..8f97d74 100644 --- a/tests/Livewire/CommentThreadingTest.php +++ b/tests/Livewire/CommentThreadingTest.php @@ -143,3 +143,102 @@ test()->assertDatabaseMissing('comments', ['id' => $reply->id]); test()->assertDatabaseMissing('comments', ['id' => $nested->id]); }); + +test('a top-level comment renders as a bordered card', function () { + $user = User::factory()->create(); + actingAs($user); + + $post = Post::factory()->create(); + $comment = Comment::factory()->author($user)->commentable($post)->create(); + + livewire(CommentComponent::class, ['comment' => $comment, 'depth' => 0]) + ->assertSeeHtml('comm:rounded-lg') + ->assertSeeHtml('comm:shadow-sm') + ->assertDontSeeHtml('commentions-thread'); +}); + +test('a reply renders as a flat row with a thread connector', function () { + $user = User::factory()->create(); + actingAs($user); + + $post = Post::factory()->create(); + $parent = Comment::factory()->author($user)->commentable($post)->create(); + $reply = Comment::factory()->author($user)->commentable($post)->create(['parent_id' => $parent->id]); + + livewire(CommentComponent::class, ['comment' => $reply, 'depth' => 1]) + ->assertDontSeeHtml('comm:shadow-sm') + ->assertSeeHtml('comm:py-2') + ->assertSeeHtml('comm:w-7') + ->assertSeeHtml('class="commentions-thread"'); +}); + +test('a comment with replies renders an accessible collapse toggle', function () { + $user = User::factory()->create(); + actingAs($user); + + $post = Post::factory()->create(); + $parent = Comment::factory()->author($user)->commentable($post)->create(); + Comment::factory()->author($user)->commentable($post)->create(['parent_id' => $parent->id]); + + livewire(CommentComponent::class, ['comment' => $parent, 'depth' => 0]) + ->assertSeeHtml(':aria-expanded') + ->assertSeeHtml('aria-controls="comment-replies-' . $parent->id . '"') + ->assertSeeHtml('id="comment-replies-' . $parent->id . '"') + ->assertSeeHtml('role="group"'); +}); + +test('the collapse toggle shows the total descendant reply count', function () { + $user = User::factory()->create(); + actingAs($user); + + $post = Post::factory()->create(); + $parent = Comment::factory()->author($user)->commentable($post)->create(); + $child = Comment::factory()->author($user)->commentable($post)->create(['parent_id' => $parent->id]); + Comment::factory()->author($user)->commentable($post)->create(['parent_id' => $child->id]); + + livewire(CommentComponent::class, ['comment' => $parent, 'depth' => 0]) + ->assertSee('2 replies'); +}); + +test('a comment with no replies renders no collapse toggle', function () { + $user = User::factory()->create(); + actingAs($user); + + $post = Post::factory()->create(); + $comment = Comment::factory()->author($user)->commentable($post)->create(); + + livewire(CommentComponent::class, ['comment' => $comment, 'depth' => 0]) + ->assertDontSeeHtml('aria-controls="comment-replies-'); +}); + +test('replies indent for the first levels then stop', function () { + config(['commentions.threading.max_depth' => 5]); + + $user = User::factory()->create(); + actingAs($user); + + $post = Post::factory()->create(); + $c0 = Comment::factory()->author($user)->commentable($post)->create(); + $c1 = Comment::factory()->author($user)->commentable($post)->create(['parent_id' => $c0->id]); + Comment::factory()->author($user)->commentable($post)->create(['parent_id' => $c1->id]); + + // A depth-0 wrapper indents the replies it renders. + livewire(CommentComponent::class, ['comment' => $c0, 'depth' => 0]) + ->assertSeeHtml('comm:pl-3'); + + // A wrapper at INDENT_CAP_DEPTH stops adding indent. + livewire(CommentComponent::class, ['comment' => $c1, 'depth' => CommentComponent::INDENT_CAP_DEPTH]) + ->assertDontSeeHtml('comm:pl-3'); +}); + +test('repliesCount counts every descendant comment', function () { + $user = User::factory()->create(); + $post = Post::factory()->create(); + + $root = Comment::factory()->author($user)->commentable($post)->create(); + $a = Comment::factory()->author($user)->commentable($post)->create(['parent_id' => $root->id]); + Comment::factory()->author($user)->commentable($post)->create(['parent_id' => $a->id]); + Comment::factory()->author($user)->commentable($post)->create(['parent_id' => $root->id]); + + expect($root->fresh()->repliesCount())->toBe(3); +});