New themes

This commit is contained in:
Saifeddine ALOUI 2025-04-03 02:06:40 +02:00
parent c53037e9e2
commit 9ea6c95886
31 changed files with 36096 additions and 5321 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

4
web/dist/index.html vendored
View File

@ -6,8 +6,8 @@
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LoLLMS WebUI</title>
<script type="module" crossorigin src="/assets/index-CVyRMqGn.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-BOiiVH6g.css">
<script type="module" crossorigin src="/assets/index-DYRg7AdD.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-D8ZSxPzY.css">
</head>
<body>
<div id="app"></div>

View File

@ -1216,6 +1216,10 @@ html{
margin-top: 0.25rem;
margin-bottom: 0.25rem;
}
.my-12{
margin-top: 3rem;
margin-bottom: 3rem;
}
.my-2{
margin-top: 0.5rem;
margin-bottom: 0.5rem;
@ -3022,6 +3026,9 @@ html{
.border-t-primary{
border-top-color: var(--color-primary);
}
.border-t-transparent{
border-top-color: transparent;
}
.bg-\[rgb\(255\2c 0\2c 0\)\]{
--tw-bg-opacity: 1;
background-color: rgb(255 0 0 / var(--tw-bg-opacity));
@ -4065,6 +4072,10 @@ html{
--tw-text-opacity: 1;
color: rgb(17 24 39 / var(--tw-text-opacity));
}
.text-green-100{
--tw-text-opacity: 1;
color: rgb(222 247 236 / var(--tw-text-opacity));
}
.text-green-200{
--tw-text-opacity: 1;
color: rgb(188 240 218 / var(--tw-text-opacity));
@ -4275,6 +4286,14 @@ html{
--tw-placeholder-opacity: 1;
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.placeholder-blue-500::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
}
.placeholder-blue-500::placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
}
.placeholder-gray-400::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(156 163 175 / var(--tw-placeholder-opacity));
@ -6545,7 +6564,7 @@ button:hover{
.group:hover .group-hover\:animate-pulse{
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
.group:hover .group-hover\:border-blue-500{
.group\/mounted:hover .group-hover\/mounted\:border-blue-500{
--tw-border-opacity: 1;
border-color: rgb(63 131 248 / var(--tw-border-opacity));
}
@ -6619,6 +6638,9 @@ button:hover{
.group\/item:hover .group-hover\/item\:opacity-100{
opacity: 1;
}
.group\/mounted:hover .group-hover\/mounted\:opacity-100{
opacity: 1;
}
.group:hover .group-hover\:opacity-100{
opacity: 1;
}
@ -7357,6 +7379,9 @@ button:hover{
--tw-bg-opacity: 1;
background-color: rgb(30 66 159 / var(--tw-bg-opacity));
}
.dark\:bg-blue-800\/30:is(.dark *){
background-color: rgb(30 66 159 / 0.3);
}
.dark\:bg-blue-800\/50:is(.dark *){
background-color: rgb(30 66 159 / 0.5);
}
@ -7437,6 +7462,10 @@ button:hover{
--tw-bg-opacity: 1;
background-color: rgb(5 122 85 / var(--tw-bg-opacity));
}
.dark\:bg-green-700:is(.dark *){
--tw-bg-opacity: 1;
background-color: rgb(4 108 78 / var(--tw-bg-opacity));
}
.dark\:bg-green-800:is(.dark *){
--tw-bg-opacity: 1;
background-color: rgb(3 84 63 / var(--tw-bg-opacity));
@ -7612,6 +7641,10 @@ button:hover{
--tw-text-opacity: 1;
color: rgb(31 41 55 / var(--tw-text-opacity));
}
.dark\:text-green-100:is(.dark *){
--tw-text-opacity: 1;
color: rgb(222 247 236 / var(--tw-text-opacity));
}
.dark\:text-green-200:is(.dark *){
--tw-text-opacity: 1;
color: rgb(188 240 218 / var(--tw-text-opacity));
@ -7675,6 +7708,10 @@ button:hover{
--tw-text-opacity: 1;
color: rgb(74 29 150 / var(--tw-text-opacity));
}
.dark\:text-red-100:is(.dark *){
--tw-text-opacity: 1;
color: rgb(253 232 232 / var(--tw-text-opacity));
}
.dark\:text-red-200:is(.dark *){
--tw-text-opacity: 1;
color: rgb(251 213 213 / var(--tw-text-opacity));
@ -7730,6 +7767,14 @@ button:hover{
--tw-text-opacity: 1;
color: rgb(99 49 18 / var(--tw-text-opacity));
}
.dark\:placeholder-blue-400:is(.dark *)::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.dark\:placeholder-blue-400:is(.dark *)::placeholder{
--tw-placeholder-opacity: 1;
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.dark\:placeholder-blue-500:is(.dark *)::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
@ -7850,7 +7895,7 @@ button:hover{
--tw-text-opacity: 1;
color: rgb(63 131 248 / var(--tw-text-opacity));
}
.group:hover .dark\:group-hover\:border-blue-400:is(.dark *){
.group\/mounted:hover .dark\:group-hover\/mounted\:border-blue-400:is(.dark *){
--tw-border-opacity: 1;
border-color: rgb(118 169 250 / var(--tw-border-opacity));
}
@ -8223,6 +8268,9 @@ button:hover{
.sm\:w-auto{
width: auto;
}
.sm\:max-w-sm{
max-width: 24rem;
}
.sm\:grid-cols-2{
grid-template-columns: repeat(2, minmax(0, 1fr));
}
@ -8330,6 +8378,9 @@ button:hover{
.md\:w-auto{
width: auto;
}
.md\:max-w-md{
max-width: 28rem;
}
.md\:max-w-xl{
max-width: 36rem;
}
@ -8465,6 +8516,9 @@ button:hover{
.xl\:w-1\/6{
width: 16.666667%;
}
.xl\:grid-cols-4{
grid-template-columns: repeat(4, minmax(0, 1fr));
}
}
@media (min-width: 1536px){
.\32xl\:h-96{

2938
web/dist/themes/borg.css vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -2094,6 +2094,10 @@ input[type='range']:is(.dark *)::-moz-range-track{
margin-top: 0.25rem;
margin-bottom: 0.25rem;
}
.my-12{
margin-top: 3rem;
margin-bottom: 3rem;
}
.my-2{
margin-top: 0.5rem;
margin-bottom: 0.5rem;
@ -3900,6 +3904,9 @@ input[type='range']:is(.dark *)::-moz-range-track{
.border-t-primary{
border-top-color: var(--color-primary);
}
.border-t-transparent{
border-top-color: transparent;
}
.bg-\[rgb\(255\2c 0\2c 0\)\]{
--tw-bg-opacity: 1;
background-color: rgb(255 0 0 / var(--tw-bg-opacity));
@ -4943,6 +4950,10 @@ input[type='range']:is(.dark *)::-moz-range-track{
--tw-text-opacity: 1;
color: rgb(17 24 39 / var(--tw-text-opacity));
}
.text-green-100{
--tw-text-opacity: 1;
color: rgb(222 247 236 / var(--tw-text-opacity));
}
.text-green-200{
--tw-text-opacity: 1;
color: rgb(188 240 218 / var(--tw-text-opacity));
@ -5153,6 +5164,14 @@ input[type='range']:is(.dark *)::-moz-range-track{
--tw-placeholder-opacity: 1;
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.placeholder-blue-500::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
}
.placeholder-blue-500::placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
}
.placeholder-gray-400::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(156 163 175 / var(--tw-placeholder-opacity));
@ -7989,7 +8008,7 @@ animation: bounce 1s infinite;
.group:hover .group-hover\:animate-pulse{
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
.group:hover .group-hover\:border-blue-500{
.group\/mounted:hover .group-hover\/mounted\:border-blue-500{
--tw-border-opacity: 1;
border-color: rgb(63 131 248 / var(--tw-border-opacity));
}
@ -8063,6 +8082,9 @@ animation: bounce 1s infinite;
.group\/item:hover .group-hover\/item\:opacity-100{
opacity: 1;
}
.group\/mounted:hover .group-hover\/mounted\:opacity-100{
opacity: 1;
}
.group:hover .group-hover\:opacity-100{
opacity: 1;
}
@ -8801,6 +8823,9 @@ animation: bounce 1s infinite;
--tw-bg-opacity: 1;
background-color: rgb(30 66 159 / var(--tw-bg-opacity));
}
.dark\:bg-blue-800\/30:is(.dark *){
background-color: rgb(30 66 159 / 0.3);
}
.dark\:bg-blue-800\/50:is(.dark *){
background-color: rgb(30 66 159 / 0.5);
}
@ -8881,6 +8906,10 @@ animation: bounce 1s infinite;
--tw-bg-opacity: 1;
background-color: rgb(5 122 85 / var(--tw-bg-opacity));
}
.dark\:bg-green-700:is(.dark *){
--tw-bg-opacity: 1;
background-color: rgb(4 108 78 / var(--tw-bg-opacity));
}
.dark\:bg-green-800:is(.dark *){
--tw-bg-opacity: 1;
background-color: rgb(3 84 63 / var(--tw-bg-opacity));
@ -9056,6 +9085,10 @@ animation: bounce 1s infinite;
--tw-text-opacity: 1;
color: rgb(31 41 55 / var(--tw-text-opacity));
}
.dark\:text-green-100:is(.dark *){
--tw-text-opacity: 1;
color: rgb(222 247 236 / var(--tw-text-opacity));
}
.dark\:text-green-200:is(.dark *){
--tw-text-opacity: 1;
color: rgb(188 240 218 / var(--tw-text-opacity));
@ -9119,6 +9152,10 @@ animation: bounce 1s infinite;
--tw-text-opacity: 1;
color: rgb(74 29 150 / var(--tw-text-opacity));
}
.dark\:text-red-100:is(.dark *){
--tw-text-opacity: 1;
color: rgb(253 232 232 / var(--tw-text-opacity));
}
.dark\:text-red-200:is(.dark *){
--tw-text-opacity: 1;
color: rgb(251 213 213 / var(--tw-text-opacity));
@ -9174,6 +9211,14 @@ animation: bounce 1s infinite;
--tw-text-opacity: 1;
color: rgb(99 49 18 / var(--tw-text-opacity));
}
.dark\:placeholder-blue-400:is(.dark *)::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.dark\:placeholder-blue-400:is(.dark *)::placeholder{
--tw-placeholder-opacity: 1;
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.dark\:placeholder-blue-500:is(.dark *)::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
@ -9294,7 +9339,7 @@ animation: bounce 1s infinite;
--tw-text-opacity: 1;
color: rgb(63 131 248 / var(--tw-text-opacity));
}
.group:hover .dark\:group-hover\:border-blue-400:is(.dark *){
.group\/mounted:hover .dark\:group-hover\/mounted\:border-blue-400:is(.dark *){
--tw-border-opacity: 1;
border-color: rgb(118 169 250 / var(--tw-border-opacity));
}
@ -9667,6 +9712,9 @@ animation: bounce 1s infinite;
.sm\:w-auto{
width: auto;
}
.sm\:max-w-sm{
max-width: 24rem;
}
.sm\:grid-cols-2{
grid-template-columns: repeat(2, minmax(0, 1fr));
}
@ -9774,6 +9822,9 @@ animation: bounce 1s infinite;
.md\:w-auto{
width: auto;
}
.md\:max-w-md{
max-width: 28rem;
}
.md\:max-w-xl{
max-width: 36rem;
}
@ -9909,6 +9960,9 @@ animation: bounce 1s infinite;
.xl\:w-1\/6{
width: 16.666667%;
}
.xl\:grid-cols-4{
grid-template-columns: repeat(4, minmax(0, 1fr));
}
}
@media (min-width: 1536px){
.\32xl\:h-96{

View File

@ -1216,6 +1216,10 @@ html{
margin-top: 0.25rem;
margin-bottom: 0.25rem;
}
.my-12{
margin-top: 3rem;
margin-bottom: 3rem;
}
.my-2{
margin-top: 0.5rem;
margin-bottom: 0.5rem;
@ -3022,6 +3026,9 @@ html{
.border-t-primary{
border-top-color: var(--color-primary);
}
.border-t-transparent{
border-top-color: transparent;
}
.bg-\[rgb\(255\2c 0\2c 0\)\]{
--tw-bg-opacity: 1;
background-color: rgb(255 0 0 / var(--tw-bg-opacity));
@ -4065,6 +4072,10 @@ html{
--tw-text-opacity: 1;
color: rgb(17 24 39 / var(--tw-text-opacity));
}
.text-green-100{
--tw-text-opacity: 1;
color: rgb(222 247 236 / var(--tw-text-opacity));
}
.text-green-200{
--tw-text-opacity: 1;
color: rgb(188 240 218 / var(--tw-text-opacity));
@ -4275,6 +4286,14 @@ html{
--tw-placeholder-opacity: 1;
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.placeholder-blue-500::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
}
.placeholder-blue-500::placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
}
.placeholder-gray-400::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(156 163 175 / var(--tw-placeholder-opacity));
@ -6482,7 +6501,7 @@ button:hover{
.group:hover .group-hover\:animate-pulse{
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
.group:hover .group-hover\:border-blue-500{
.group\/mounted:hover .group-hover\/mounted\:border-blue-500{
--tw-border-opacity: 1;
border-color: rgb(63 131 248 / var(--tw-border-opacity));
}
@ -6556,6 +6575,9 @@ button:hover{
.group\/item:hover .group-hover\/item\:opacity-100{
opacity: 1;
}
.group\/mounted:hover .group-hover\/mounted\:opacity-100{
opacity: 1;
}
.group:hover .group-hover\:opacity-100{
opacity: 1;
}
@ -7294,6 +7316,9 @@ button:hover{
--tw-bg-opacity: 1;
background-color: rgb(30 66 159 / var(--tw-bg-opacity));
}
.dark\:bg-blue-800\/30:is(.dark *){
background-color: rgb(30 66 159 / 0.3);
}
.dark\:bg-blue-800\/50:is(.dark *){
background-color: rgb(30 66 159 / 0.5);
}
@ -7374,6 +7399,10 @@ button:hover{
--tw-bg-opacity: 1;
background-color: rgb(5 122 85 / var(--tw-bg-opacity));
}
.dark\:bg-green-700:is(.dark *){
--tw-bg-opacity: 1;
background-color: rgb(4 108 78 / var(--tw-bg-opacity));
}
.dark\:bg-green-800:is(.dark *){
--tw-bg-opacity: 1;
background-color: rgb(3 84 63 / var(--tw-bg-opacity));
@ -7549,6 +7578,10 @@ button:hover{
--tw-text-opacity: 1;
color: rgb(31 41 55 / var(--tw-text-opacity));
}
.dark\:text-green-100:is(.dark *){
--tw-text-opacity: 1;
color: rgb(222 247 236 / var(--tw-text-opacity));
}
.dark\:text-green-200:is(.dark *){
--tw-text-opacity: 1;
color: rgb(188 240 218 / var(--tw-text-opacity));
@ -7612,6 +7645,10 @@ button:hover{
--tw-text-opacity: 1;
color: rgb(74 29 150 / var(--tw-text-opacity));
}
.dark\:text-red-100:is(.dark *){
--tw-text-opacity: 1;
color: rgb(253 232 232 / var(--tw-text-opacity));
}
.dark\:text-red-200:is(.dark *){
--tw-text-opacity: 1;
color: rgb(251 213 213 / var(--tw-text-opacity));
@ -7667,6 +7704,14 @@ button:hover{
--tw-text-opacity: 1;
color: rgb(99 49 18 / var(--tw-text-opacity));
}
.dark\:placeholder-blue-400:is(.dark *)::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.dark\:placeholder-blue-400:is(.dark *)::placeholder{
--tw-placeholder-opacity: 1;
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.dark\:placeholder-blue-500:is(.dark *)::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
@ -7787,7 +7832,7 @@ button:hover{
--tw-text-opacity: 1;
color: rgb(63 131 248 / var(--tw-text-opacity));
}
.group:hover .dark\:group-hover\:border-blue-400:is(.dark *){
.group\/mounted:hover .dark\:group-hover\/mounted\:border-blue-400:is(.dark *){
--tw-border-opacity: 1;
border-color: rgb(118 169 250 / var(--tw-border-opacity));
}
@ -8160,6 +8205,9 @@ button:hover{
.sm\:w-auto{
width: auto;
}
.sm\:max-w-sm{
max-width: 24rem;
}
.sm\:grid-cols-2{
grid-template-columns: repeat(2, minmax(0, 1fr));
}
@ -8267,6 +8315,9 @@ button:hover{
.md\:w-auto{
width: auto;
}
.md\:max-w-md{
max-width: 28rem;
}
.md\:max-w-xl{
max-width: 36rem;
}
@ -8402,6 +8453,9 @@ button:hover{
.xl\:w-1\/6{
width: 16.666667%;
}
.xl\:grid-cols-4{
grid-template-columns: repeat(4, minmax(0, 1fr));
}
}
@media (min-width: 1536px){
.\32xl\:h-96{

9779
web/dist/themes/matrix.css vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1476,6 +1476,11 @@ body {
margin-bottom: 0.25rem;
}
.my-12{
margin-top: 3rem;
margin-bottom: 3rem;
}
.my-2{
margin-top: 0.5rem;
margin-bottom: 0.5rem;
@ -3832,6 +3837,10 @@ body {
border-top-color: var(--color-primary);
}
.border-t-transparent{
border-top-color: transparent;
}
.bg-\[rgb\(255\2c 0\2c 0\)\]{
--tw-bg-opacity: 1;
background-color: rgb(255 0 0 / var(--tw-bg-opacity));
@ -5170,6 +5179,11 @@ body {
color: rgb(17 24 39 / var(--tw-text-opacity));
}
.text-green-100{
--tw-text-opacity: 1;
color: rgb(222 247 236 / var(--tw-text-opacity));
}
.text-green-200{
--tw-text-opacity: 1;
color: rgb(188 240 218 / var(--tw-text-opacity));
@ -5435,6 +5449,16 @@ body {
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.placeholder-blue-500::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
}
.placeholder-blue-500::placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
}
.placeholder-gray-400::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(156 163 175 / var(--tw-placeholder-opacity));
@ -8075,7 +8099,7 @@ button:hover{
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
.group:hover .group-hover\:border-blue-500{
.group\/mounted:hover .group-hover\/mounted\:border-blue-500{
--tw-border-opacity: 1;
border-color: rgb(63 131 248 / var(--tw-border-opacity));
}
@ -8168,6 +8192,10 @@ button:hover{
opacity: 1;
}
.group\/mounted:hover .group-hover\/mounted\:opacity-100{
opacity: 1;
}
.group:hover .group-hover\:opacity-100{
opacity: 1;
}
@ -9097,6 +9125,10 @@ button:hover{
background-color: rgb(30 66 159 / var(--tw-bg-opacity));
}
.dark\:bg-blue-800\/30:is(.dark *){
background-color: rgb(30 66 159 / 0.3);
}
.dark\:bg-blue-800\/50:is(.dark *){
background-color: rgb(30 66 159 / 0.5);
}
@ -9200,6 +9232,11 @@ button:hover{
background-color: rgb(5 122 85 / var(--tw-bg-opacity));
}
.dark\:bg-green-700:is(.dark *){
--tw-bg-opacity: 1;
background-color: rgb(4 108 78 / var(--tw-bg-opacity));
}
.dark\:bg-green-800:is(.dark *){
--tw-bg-opacity: 1;
background-color: rgb(3 84 63 / var(--tw-bg-opacity));
@ -9421,6 +9458,11 @@ button:hover{
color: rgb(31 41 55 / var(--tw-text-opacity));
}
.dark\:text-green-100:is(.dark *){
--tw-text-opacity: 1;
color: rgb(222 247 236 / var(--tw-text-opacity));
}
.dark\:text-green-200:is(.dark *){
--tw-text-opacity: 1;
color: rgb(188 240 218 / var(--tw-text-opacity));
@ -9500,6 +9542,11 @@ button:hover{
color: rgb(74 29 150 / var(--tw-text-opacity));
}
.dark\:text-red-100:is(.dark *){
--tw-text-opacity: 1;
color: rgb(253 232 232 / var(--tw-text-opacity));
}
.dark\:text-red-200:is(.dark *){
--tw-text-opacity: 1;
color: rgb(251 213 213 / var(--tw-text-opacity));
@ -9569,6 +9616,16 @@ button:hover{
color: rgb(99 49 18 / var(--tw-text-opacity));
}
.dark\:placeholder-blue-400:is(.dark *)::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.dark\:placeholder-blue-400:is(.dark *)::placeholder{
--tw-placeholder-opacity: 1;
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.dark\:placeholder-blue-500:is(.dark *)::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
@ -9722,7 +9779,7 @@ button:hover{
color: rgb(63 131 248 / var(--tw-text-opacity));
}
.group:hover .dark\:group-hover\:border-blue-400:is(.dark *){
.group\/mounted:hover .dark\:group-hover\/mounted\:border-blue-400:is(.dark *){
--tw-border-opacity: 1;
border-color: rgb(118 169 250 / var(--tw-border-opacity));
}
@ -10197,6 +10254,10 @@ button:hover{
width: auto;
}
.sm\:max-w-sm{
max-width: 24rem;
}
.sm\:grid-cols-2{
grid-template-columns: repeat(2, minmax(0, 1fr));
}
@ -10339,6 +10400,10 @@ button:hover{
width: auto;
}
.md\:max-w-md{
max-width: 28rem;
}
.md\:max-w-xl{
max-width: 36rem;
}
@ -10514,6 +10579,10 @@ button:hover{
.xl\:w-1\/6{
width: 16.666667%;
}
.xl\:grid-cols-4{
grid-template-columns: repeat(4, minmax(0, 1fr));
}
}
@media (min-width: 1536px){

View File

@ -1476,6 +1476,11 @@ body {
margin-bottom: 0.25rem;
}
.my-12{
margin-top: 3rem;
margin-bottom: 3rem;
}
.my-2{
margin-top: 0.5rem;
margin-bottom: 0.5rem;
@ -3832,6 +3837,10 @@ body {
border-top-color: var(--color-primary);
}
.border-t-transparent{
border-top-color: transparent;
}
.bg-\[rgb\(255\2c 0\2c 0\)\]{
--tw-bg-opacity: 1;
background-color: rgb(255 0 0 / var(--tw-bg-opacity));
@ -5170,6 +5179,11 @@ body {
color: rgb(17 24 39 / var(--tw-text-opacity));
}
.text-green-100{
--tw-text-opacity: 1;
color: rgb(222 247 236 / var(--tw-text-opacity));
}
.text-green-200{
--tw-text-opacity: 1;
color: rgb(188 240 218 / var(--tw-text-opacity));
@ -5435,6 +5449,16 @@ body {
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.placeholder-blue-500::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
}
.placeholder-blue-500::placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
}
.placeholder-gray-400::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(156 163 175 / var(--tw-placeholder-opacity));
@ -8052,7 +8076,7 @@ button:hover{
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
.group:hover .group-hover\:border-blue-500{
.group\/mounted:hover .group-hover\/mounted\:border-blue-500{
--tw-border-opacity: 1;
border-color: rgb(63 131 248 / var(--tw-border-opacity));
}
@ -8145,6 +8169,10 @@ button:hover{
opacity: 1;
}
.group\/mounted:hover .group-hover\/mounted\:opacity-100{
opacity: 1;
}
.group:hover .group-hover\:opacity-100{
opacity: 1;
}
@ -9074,6 +9102,10 @@ button:hover{
background-color: rgb(30 66 159 / var(--tw-bg-opacity));
}
.dark\:bg-blue-800\/30:is(.dark *){
background-color: rgb(30 66 159 / 0.3);
}
.dark\:bg-blue-800\/50:is(.dark *){
background-color: rgb(30 66 159 / 0.5);
}
@ -9177,6 +9209,11 @@ button:hover{
background-color: rgb(5 122 85 / var(--tw-bg-opacity));
}
.dark\:bg-green-700:is(.dark *){
--tw-bg-opacity: 1;
background-color: rgb(4 108 78 / var(--tw-bg-opacity));
}
.dark\:bg-green-800:is(.dark *){
--tw-bg-opacity: 1;
background-color: rgb(3 84 63 / var(--tw-bg-opacity));
@ -9398,6 +9435,11 @@ button:hover{
color: rgb(31 41 55 / var(--tw-text-opacity));
}
.dark\:text-green-100:is(.dark *){
--tw-text-opacity: 1;
color: rgb(222 247 236 / var(--tw-text-opacity));
}
.dark\:text-green-200:is(.dark *){
--tw-text-opacity: 1;
color: rgb(188 240 218 / var(--tw-text-opacity));
@ -9477,6 +9519,11 @@ button:hover{
color: rgb(74 29 150 / var(--tw-text-opacity));
}
.dark\:text-red-100:is(.dark *){
--tw-text-opacity: 1;
color: rgb(253 232 232 / var(--tw-text-opacity));
}
.dark\:text-red-200:is(.dark *){
--tw-text-opacity: 1;
color: rgb(251 213 213 / var(--tw-text-opacity));
@ -9546,6 +9593,16 @@ button:hover{
color: rgb(99 49 18 / var(--tw-text-opacity));
}
.dark\:placeholder-blue-400:is(.dark *)::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.dark\:placeholder-blue-400:is(.dark *)::placeholder{
--tw-placeholder-opacity: 1;
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.dark\:placeholder-blue-500:is(.dark *)::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
@ -9699,7 +9756,7 @@ button:hover{
color: rgb(63 131 248 / var(--tw-text-opacity));
}
.group:hover .dark\:group-hover\:border-blue-400:is(.dark *){
.group\/mounted:hover .dark\:group-hover\/mounted\:border-blue-400:is(.dark *){
--tw-border-opacity: 1;
border-color: rgb(118 169 250 / var(--tw-border-opacity));
}
@ -10174,6 +10231,10 @@ button:hover{
width: auto;
}
.sm\:max-w-sm{
max-width: 24rem;
}
.sm\:grid-cols-2{
grid-template-columns: repeat(2, minmax(0, 1fr));
}
@ -10316,6 +10377,10 @@ button:hover{
width: auto;
}
.md\:max-w-md{
max-width: 28rem;
}
.md\:max-w-xl{
max-width: 36rem;
}
@ -10491,6 +10556,10 @@ button:hover{
.xl\:w-1\/6{
width: 16.666667%;
}
.xl\:grid-cols-4{
grid-template-columns: repeat(4, minmax(0, 1fr));
}
}
@media (min-width: 1536px){

File diff suppressed because it is too large Load Diff

View File

@ -1216,6 +1216,10 @@ html{
margin-top: 0.25rem;
margin-bottom: 0.25rem;
}
.my-12{
margin-top: 3rem;
margin-bottom: 3rem;
}
.my-2{
margin-top: 0.5rem;
margin-bottom: 0.5rem;
@ -3022,6 +3026,9 @@ html{
.border-t-primary{
border-top-color: var(--color-primary);
}
.border-t-transparent{
border-top-color: transparent;
}
.bg-\[rgb\(255\2c 0\2c 0\)\]{
--tw-bg-opacity: 1;
background-color: rgb(255 0 0 / var(--tw-bg-opacity));
@ -4065,6 +4072,10 @@ html{
--tw-text-opacity: 1;
color: rgb(17 24 39 / var(--tw-text-opacity));
}
.text-green-100{
--tw-text-opacity: 1;
color: rgb(222 247 236 / var(--tw-text-opacity));
}
.text-green-200{
--tw-text-opacity: 1;
color: rgb(188 240 218 / var(--tw-text-opacity));
@ -4275,6 +4286,14 @@ html{
--tw-placeholder-opacity: 1;
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.placeholder-blue-500::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
}
.placeholder-blue-500::placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
}
.placeholder-gray-400::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(156 163 175 / var(--tw-placeholder-opacity));
@ -6445,7 +6464,7 @@ button:hover{
.group:hover .group-hover\:animate-pulse{
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
.group:hover .group-hover\:border-blue-500{
.group\/mounted:hover .group-hover\/mounted\:border-blue-500{
--tw-border-opacity: 1;
border-color: rgb(63 131 248 / var(--tw-border-opacity));
}
@ -6519,6 +6538,9 @@ button:hover{
.group\/item:hover .group-hover\/item\:opacity-100{
opacity: 1;
}
.group\/mounted:hover .group-hover\/mounted\:opacity-100{
opacity: 1;
}
.group:hover .group-hover\:opacity-100{
opacity: 1;
}
@ -7257,6 +7279,9 @@ button:hover{
--tw-bg-opacity: 1;
background-color: rgb(30 66 159 / var(--tw-bg-opacity));
}
.dark\:bg-blue-800\/30:is(.dark *){
background-color: rgb(30 66 159 / 0.3);
}
.dark\:bg-blue-800\/50:is(.dark *){
background-color: rgb(30 66 159 / 0.5);
}
@ -7337,6 +7362,10 @@ button:hover{
--tw-bg-opacity: 1;
background-color: rgb(5 122 85 / var(--tw-bg-opacity));
}
.dark\:bg-green-700:is(.dark *){
--tw-bg-opacity: 1;
background-color: rgb(4 108 78 / var(--tw-bg-opacity));
}
.dark\:bg-green-800:is(.dark *){
--tw-bg-opacity: 1;
background-color: rgb(3 84 63 / var(--tw-bg-opacity));
@ -7512,6 +7541,10 @@ button:hover{
--tw-text-opacity: 1;
color: rgb(31 41 55 / var(--tw-text-opacity));
}
.dark\:text-green-100:is(.dark *){
--tw-text-opacity: 1;
color: rgb(222 247 236 / var(--tw-text-opacity));
}
.dark\:text-green-200:is(.dark *){
--tw-text-opacity: 1;
color: rgb(188 240 218 / var(--tw-text-opacity));
@ -7575,6 +7608,10 @@ button:hover{
--tw-text-opacity: 1;
color: rgb(74 29 150 / var(--tw-text-opacity));
}
.dark\:text-red-100:is(.dark *){
--tw-text-opacity: 1;
color: rgb(253 232 232 / var(--tw-text-opacity));
}
.dark\:text-red-200:is(.dark *){
--tw-text-opacity: 1;
color: rgb(251 213 213 / var(--tw-text-opacity));
@ -7630,6 +7667,14 @@ button:hover{
--tw-text-opacity: 1;
color: rgb(99 49 18 / var(--tw-text-opacity));
}
.dark\:placeholder-blue-400:is(.dark *)::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.dark\:placeholder-blue-400:is(.dark *)::placeholder{
--tw-placeholder-opacity: 1;
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.dark\:placeholder-blue-500:is(.dark *)::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
@ -7750,7 +7795,7 @@ button:hover{
--tw-text-opacity: 1;
color: rgb(63 131 248 / var(--tw-text-opacity));
}
.group:hover .dark\:group-hover\:border-blue-400:is(.dark *){
.group\/mounted:hover .dark\:group-hover\/mounted\:border-blue-400:is(.dark *){
--tw-border-opacity: 1;
border-color: rgb(118 169 250 / var(--tw-border-opacity));
}
@ -8123,6 +8168,9 @@ button:hover{
.sm\:w-auto{
width: auto;
}
.sm\:max-w-sm{
max-width: 24rem;
}
.sm\:grid-cols-2{
grid-template-columns: repeat(2, minmax(0, 1fr));
}
@ -8230,6 +8278,9 @@ button:hover{
.md\:w-auto{
width: auto;
}
.md\:max-w-md{
max-width: 28rem;
}
.md\:max-w-xl{
max-width: 36rem;
}
@ -8365,6 +8416,9 @@ button:hover{
.xl\:w-1\/6{
width: 16.666667%;
}
.xl\:grid-cols-4{
grid-template-columns: repeat(4, minmax(0, 1fr));
}
}
@media (min-width: 1536px){
.\32xl\:h-96{

View File

@ -1476,6 +1476,11 @@ body {
margin-bottom: 0.25rem;
}
.my-12{
margin-top: 3rem;
margin-bottom: 3rem;
}
.my-2{
margin-top: 0.5rem;
margin-bottom: 0.5rem;
@ -3832,6 +3837,10 @@ body {
border-top-color: var(--color-primary);
}
.border-t-transparent{
border-top-color: transparent;
}
.bg-\[rgb\(255\2c 0\2c 0\)\]{
--tw-bg-opacity: 1;
background-color: rgb(255 0 0 / var(--tw-bg-opacity));
@ -5170,6 +5179,11 @@ body {
color: rgb(17 24 39 / var(--tw-text-opacity));
}
.text-green-100{
--tw-text-opacity: 1;
color: rgb(222 247 236 / var(--tw-text-opacity));
}
.text-green-200{
--tw-text-opacity: 1;
color: rgb(188 240 218 / var(--tw-text-opacity));
@ -5435,6 +5449,16 @@ body {
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.placeholder-blue-500::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
}
.placeholder-blue-500::placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
}
.placeholder-gray-400::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(156 163 175 / var(--tw-placeholder-opacity));
@ -7929,7 +7953,7 @@ button:hover{
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
.group:hover .group-hover\:border-blue-500{
.group\/mounted:hover .group-hover\/mounted\:border-blue-500{
--tw-border-opacity: 1;
border-color: rgb(63 131 248 / var(--tw-border-opacity));
}
@ -8022,6 +8046,10 @@ button:hover{
opacity: 1;
}
.group\/mounted:hover .group-hover\/mounted\:opacity-100{
opacity: 1;
}
.group:hover .group-hover\:opacity-100{
opacity: 1;
}
@ -8951,6 +8979,10 @@ button:hover{
background-color: rgb(30 66 159 / var(--tw-bg-opacity));
}
.dark\:bg-blue-800\/30:is(.dark *){
background-color: rgb(30 66 159 / 0.3);
}
.dark\:bg-blue-800\/50:is(.dark *){
background-color: rgb(30 66 159 / 0.5);
}
@ -9054,6 +9086,11 @@ button:hover{
background-color: rgb(5 122 85 / var(--tw-bg-opacity));
}
.dark\:bg-green-700:is(.dark *){
--tw-bg-opacity: 1;
background-color: rgb(4 108 78 / var(--tw-bg-opacity));
}
.dark\:bg-green-800:is(.dark *){
--tw-bg-opacity: 1;
background-color: rgb(3 84 63 / var(--tw-bg-opacity));
@ -9275,6 +9312,11 @@ button:hover{
color: rgb(31 41 55 / var(--tw-text-opacity));
}
.dark\:text-green-100:is(.dark *){
--tw-text-opacity: 1;
color: rgb(222 247 236 / var(--tw-text-opacity));
}
.dark\:text-green-200:is(.dark *){
--tw-text-opacity: 1;
color: rgb(188 240 218 / var(--tw-text-opacity));
@ -9354,6 +9396,11 @@ button:hover{
color: rgb(74 29 150 / var(--tw-text-opacity));
}
.dark\:text-red-100:is(.dark *){
--tw-text-opacity: 1;
color: rgb(253 232 232 / var(--tw-text-opacity));
}
.dark\:text-red-200:is(.dark *){
--tw-text-opacity: 1;
color: rgb(251 213 213 / var(--tw-text-opacity));
@ -9423,6 +9470,16 @@ button:hover{
color: rgb(99 49 18 / var(--tw-text-opacity));
}
.dark\:placeholder-blue-400:is(.dark *)::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.dark\:placeholder-blue-400:is(.dark *)::placeholder{
--tw-placeholder-opacity: 1;
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.dark\:placeholder-blue-500:is(.dark *)::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
@ -9576,7 +9633,7 @@ button:hover{
color: rgb(63 131 248 / var(--tw-text-opacity));
}
.group:hover .dark\:group-hover\:border-blue-400:is(.dark *){
.group\/mounted:hover .dark\:group-hover\/mounted\:border-blue-400:is(.dark *){
--tw-border-opacity: 1;
border-color: rgb(118 169 250 / var(--tw-border-opacity));
}
@ -10051,6 +10108,10 @@ button:hover{
width: auto;
}
.sm\:max-w-sm{
max-width: 24rem;
}
.sm\:grid-cols-2{
grid-template-columns: repeat(2, minmax(0, 1fr));
}
@ -10193,6 +10254,10 @@ button:hover{
width: auto;
}
.md\:max-w-md{
max-width: 28rem;
}
.md\:max-w-xl{
max-width: 36rem;
}
@ -10368,6 +10433,10 @@ button:hover{
.xl\:w-1\/6{
width: 16.666667%;
}
.xl\:grid-cols-4{
grid-template-columns: repeat(4, minmax(0, 1fr));
}
}
@media (min-width: 1536px){

View File

@ -1216,6 +1216,10 @@ html{
margin-top: 0.25rem;
margin-bottom: 0.25rem;
}
.my-12{
margin-top: 3rem;
margin-bottom: 3rem;
}
.my-2{
margin-top: 0.5rem;
margin-bottom: 0.5rem;
@ -3022,6 +3026,9 @@ html{
.border-t-primary{
border-top-color: var(--color-primary);
}
.border-t-transparent{
border-top-color: transparent;
}
.bg-\[rgb\(255\2c 0\2c 0\)\]{
--tw-bg-opacity: 1;
background-color: rgb(255 0 0 / var(--tw-bg-opacity));
@ -4065,6 +4072,10 @@ html{
--tw-text-opacity: 1;
color: rgb(17 24 39 / var(--tw-text-opacity));
}
.text-green-100{
--tw-text-opacity: 1;
color: rgb(222 247 236 / var(--tw-text-opacity));
}
.text-green-200{
--tw-text-opacity: 1;
color: rgb(188 240 218 / var(--tw-text-opacity));
@ -4275,6 +4286,14 @@ html{
--tw-placeholder-opacity: 1;
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.placeholder-blue-500::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
}
.placeholder-blue-500::placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
}
.placeholder-gray-400::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(156 163 175 / var(--tw-placeholder-opacity));
@ -6545,7 +6564,7 @@ button:hover{
.group:hover .group-hover\:animate-pulse{
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
.group:hover .group-hover\:border-blue-500{
.group\/mounted:hover .group-hover\/mounted\:border-blue-500{
--tw-border-opacity: 1;
border-color: rgb(63 131 248 / var(--tw-border-opacity));
}
@ -6619,6 +6638,9 @@ button:hover{
.group\/item:hover .group-hover\/item\:opacity-100{
opacity: 1;
}
.group\/mounted:hover .group-hover\/mounted\:opacity-100{
opacity: 1;
}
.group:hover .group-hover\:opacity-100{
opacity: 1;
}
@ -7357,6 +7379,9 @@ button:hover{
--tw-bg-opacity: 1;
background-color: rgb(30 66 159 / var(--tw-bg-opacity));
}
.dark\:bg-blue-800\/30:is(.dark *){
background-color: rgb(30 66 159 / 0.3);
}
.dark\:bg-blue-800\/50:is(.dark *){
background-color: rgb(30 66 159 / 0.5);
}
@ -7437,6 +7462,10 @@ button:hover{
--tw-bg-opacity: 1;
background-color: rgb(5 122 85 / var(--tw-bg-opacity));
}
.dark\:bg-green-700:is(.dark *){
--tw-bg-opacity: 1;
background-color: rgb(4 108 78 / var(--tw-bg-opacity));
}
.dark\:bg-green-800:is(.dark *){
--tw-bg-opacity: 1;
background-color: rgb(3 84 63 / var(--tw-bg-opacity));
@ -7612,6 +7641,10 @@ button:hover{
--tw-text-opacity: 1;
color: rgb(31 41 55 / var(--tw-text-opacity));
}
.dark\:text-green-100:is(.dark *){
--tw-text-opacity: 1;
color: rgb(222 247 236 / var(--tw-text-opacity));
}
.dark\:text-green-200:is(.dark *){
--tw-text-opacity: 1;
color: rgb(188 240 218 / var(--tw-text-opacity));
@ -7675,6 +7708,10 @@ button:hover{
--tw-text-opacity: 1;
color: rgb(74 29 150 / var(--tw-text-opacity));
}
.dark\:text-red-100:is(.dark *){
--tw-text-opacity: 1;
color: rgb(253 232 232 / var(--tw-text-opacity));
}
.dark\:text-red-200:is(.dark *){
--tw-text-opacity: 1;
color: rgb(251 213 213 / var(--tw-text-opacity));
@ -7730,6 +7767,14 @@ button:hover{
--tw-text-opacity: 1;
color: rgb(99 49 18 / var(--tw-text-opacity));
}
.dark\:placeholder-blue-400:is(.dark *)::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.dark\:placeholder-blue-400:is(.dark *)::placeholder{
--tw-placeholder-opacity: 1;
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.dark\:placeholder-blue-500:is(.dark *)::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
@ -7850,7 +7895,7 @@ button:hover{
--tw-text-opacity: 1;
color: rgb(63 131 248 / var(--tw-text-opacity));
}
.group:hover .dark\:group-hover\:border-blue-400:is(.dark *){
.group\/mounted:hover .dark\:group-hover\/mounted\:border-blue-400:is(.dark *){
--tw-border-opacity: 1;
border-color: rgb(118 169 250 / var(--tw-border-opacity));
}
@ -8223,6 +8268,9 @@ button:hover{
.sm\:w-auto{
width: auto;
}
.sm\:max-w-sm{
max-width: 24rem;
}
.sm\:grid-cols-2{
grid-template-columns: repeat(2, minmax(0, 1fr));
}
@ -8330,6 +8378,9 @@ button:hover{
.md\:w-auto{
width: auto;
}
.md\:max-w-md{
max-width: 28rem;
}
.md\:max-w-xl{
max-width: 36rem;
}
@ -8465,6 +8516,9 @@ button:hover{
.xl\:w-1\/6{
width: 16.666667%;
}
.xl\:grid-cols-4{
grid-template-columns: repeat(4, minmax(0, 1fr));
}
}
@media (min-width: 1536px){
.\32xl\:h-96{

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -2094,6 +2094,10 @@ input[type='range']:is(.dark *)::-moz-range-track{
margin-top: 0.25rem;
margin-bottom: 0.25rem;
}
.my-12{
margin-top: 3rem;
margin-bottom: 3rem;
}
.my-2{
margin-top: 0.5rem;
margin-bottom: 0.5rem;
@ -3900,6 +3904,9 @@ input[type='range']:is(.dark *)::-moz-range-track{
.border-t-primary{
border-top-color: var(--color-primary);
}
.border-t-transparent{
border-top-color: transparent;
}
.bg-\[rgb\(255\2c 0\2c 0\)\]{
--tw-bg-opacity: 1;
background-color: rgb(255 0 0 / var(--tw-bg-opacity));
@ -4943,6 +4950,10 @@ input[type='range']:is(.dark *)::-moz-range-track{
--tw-text-opacity: 1;
color: rgb(17 24 39 / var(--tw-text-opacity));
}
.text-green-100{
--tw-text-opacity: 1;
color: rgb(222 247 236 / var(--tw-text-opacity));
}
.text-green-200{
--tw-text-opacity: 1;
color: rgb(188 240 218 / var(--tw-text-opacity));
@ -5153,6 +5164,14 @@ input[type='range']:is(.dark *)::-moz-range-track{
--tw-placeholder-opacity: 1;
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.placeholder-blue-500::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
}
.placeholder-blue-500::placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
}
.placeholder-gray-400::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(156 163 175 / var(--tw-placeholder-opacity));
@ -7989,7 +8008,7 @@ animation: bounce 1s infinite;
.group:hover .group-hover\:animate-pulse{
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
.group:hover .group-hover\:border-blue-500{
.group\/mounted:hover .group-hover\/mounted\:border-blue-500{
--tw-border-opacity: 1;
border-color: rgb(63 131 248 / var(--tw-border-opacity));
}
@ -8063,6 +8082,9 @@ animation: bounce 1s infinite;
.group\/item:hover .group-hover\/item\:opacity-100{
opacity: 1;
}
.group\/mounted:hover .group-hover\/mounted\:opacity-100{
opacity: 1;
}
.group:hover .group-hover\:opacity-100{
opacity: 1;
}
@ -8801,6 +8823,9 @@ animation: bounce 1s infinite;
--tw-bg-opacity: 1;
background-color: rgb(30 66 159 / var(--tw-bg-opacity));
}
.dark\:bg-blue-800\/30:is(.dark *){
background-color: rgb(30 66 159 / 0.3);
}
.dark\:bg-blue-800\/50:is(.dark *){
background-color: rgb(30 66 159 / 0.5);
}
@ -8881,6 +8906,10 @@ animation: bounce 1s infinite;
--tw-bg-opacity: 1;
background-color: rgb(5 122 85 / var(--tw-bg-opacity));
}
.dark\:bg-green-700:is(.dark *){
--tw-bg-opacity: 1;
background-color: rgb(4 108 78 / var(--tw-bg-opacity));
}
.dark\:bg-green-800:is(.dark *){
--tw-bg-opacity: 1;
background-color: rgb(3 84 63 / var(--tw-bg-opacity));
@ -9056,6 +9085,10 @@ animation: bounce 1s infinite;
--tw-text-opacity: 1;
color: rgb(31 41 55 / var(--tw-text-opacity));
}
.dark\:text-green-100:is(.dark *){
--tw-text-opacity: 1;
color: rgb(222 247 236 / var(--tw-text-opacity));
}
.dark\:text-green-200:is(.dark *){
--tw-text-opacity: 1;
color: rgb(188 240 218 / var(--tw-text-opacity));
@ -9119,6 +9152,10 @@ animation: bounce 1s infinite;
--tw-text-opacity: 1;
color: rgb(74 29 150 / var(--tw-text-opacity));
}
.dark\:text-red-100:is(.dark *){
--tw-text-opacity: 1;
color: rgb(253 232 232 / var(--tw-text-opacity));
}
.dark\:text-red-200:is(.dark *){
--tw-text-opacity: 1;
color: rgb(251 213 213 / var(--tw-text-opacity));
@ -9174,6 +9211,14 @@ animation: bounce 1s infinite;
--tw-text-opacity: 1;
color: rgb(99 49 18 / var(--tw-text-opacity));
}
.dark\:placeholder-blue-400:is(.dark *)::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.dark\:placeholder-blue-400:is(.dark *)::placeholder{
--tw-placeholder-opacity: 1;
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.dark\:placeholder-blue-500:is(.dark *)::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
@ -9294,7 +9339,7 @@ animation: bounce 1s infinite;
--tw-text-opacity: 1;
color: rgb(63 131 248 / var(--tw-text-opacity));
}
.group:hover .dark\:group-hover\:border-blue-400:is(.dark *){
.group\/mounted:hover .dark\:group-hover\/mounted\:border-blue-400:is(.dark *){
--tw-border-opacity: 1;
border-color: rgb(118 169 250 / var(--tw-border-opacity));
}
@ -9667,6 +9712,9 @@ animation: bounce 1s infinite;
.sm\:w-auto{
width: auto;
}
.sm\:max-w-sm{
max-width: 24rem;
}
.sm\:grid-cols-2{
grid-template-columns: repeat(2, minmax(0, 1fr));
}
@ -9774,6 +9822,9 @@ animation: bounce 1s infinite;
.md\:w-auto{
width: auto;
}
.md\:max-w-md{
max-width: 28rem;
}
.md\:max-w-xl{
max-width: 36rem;
}
@ -9909,6 +9960,9 @@ animation: bounce 1s infinite;
.xl\:w-1\/6{
width: 16.666667%;
}
.xl\:grid-cols-4{
grid-template-columns: repeat(4, minmax(0, 1fr));
}
}
@media (min-width: 1536px){
.\32xl\:h-96{

View File

@ -1216,6 +1216,10 @@ html{
margin-top: 0.25rem;
margin-bottom: 0.25rem;
}
.my-12{
margin-top: 3rem;
margin-bottom: 3rem;
}
.my-2{
margin-top: 0.5rem;
margin-bottom: 0.5rem;
@ -3022,6 +3026,9 @@ html{
.border-t-primary{
border-top-color: var(--color-primary);
}
.border-t-transparent{
border-top-color: transparent;
}
.bg-\[rgb\(255\2c 0\2c 0\)\]{
--tw-bg-opacity: 1;
background-color: rgb(255 0 0 / var(--tw-bg-opacity));
@ -4065,6 +4072,10 @@ html{
--tw-text-opacity: 1;
color: rgb(17 24 39 / var(--tw-text-opacity));
}
.text-green-100{
--tw-text-opacity: 1;
color: rgb(222 247 236 / var(--tw-text-opacity));
}
.text-green-200{
--tw-text-opacity: 1;
color: rgb(188 240 218 / var(--tw-text-opacity));
@ -4275,6 +4286,14 @@ html{
--tw-placeholder-opacity: 1;
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.placeholder-blue-500::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
}
.placeholder-blue-500::placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
}
.placeholder-gray-400::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(156 163 175 / var(--tw-placeholder-opacity));
@ -6482,7 +6501,7 @@ button:hover{
.group:hover .group-hover\:animate-pulse{
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
.group:hover .group-hover\:border-blue-500{
.group\/mounted:hover .group-hover\/mounted\:border-blue-500{
--tw-border-opacity: 1;
border-color: rgb(63 131 248 / var(--tw-border-opacity));
}
@ -6556,6 +6575,9 @@ button:hover{
.group\/item:hover .group-hover\/item\:opacity-100{
opacity: 1;
}
.group\/mounted:hover .group-hover\/mounted\:opacity-100{
opacity: 1;
}
.group:hover .group-hover\:opacity-100{
opacity: 1;
}
@ -7294,6 +7316,9 @@ button:hover{
--tw-bg-opacity: 1;
background-color: rgb(30 66 159 / var(--tw-bg-opacity));
}
.dark\:bg-blue-800\/30:is(.dark *){
background-color: rgb(30 66 159 / 0.3);
}
.dark\:bg-blue-800\/50:is(.dark *){
background-color: rgb(30 66 159 / 0.5);
}
@ -7374,6 +7399,10 @@ button:hover{
--tw-bg-opacity: 1;
background-color: rgb(5 122 85 / var(--tw-bg-opacity));
}
.dark\:bg-green-700:is(.dark *){
--tw-bg-opacity: 1;
background-color: rgb(4 108 78 / var(--tw-bg-opacity));
}
.dark\:bg-green-800:is(.dark *){
--tw-bg-opacity: 1;
background-color: rgb(3 84 63 / var(--tw-bg-opacity));
@ -7549,6 +7578,10 @@ button:hover{
--tw-text-opacity: 1;
color: rgb(31 41 55 / var(--tw-text-opacity));
}
.dark\:text-green-100:is(.dark *){
--tw-text-opacity: 1;
color: rgb(222 247 236 / var(--tw-text-opacity));
}
.dark\:text-green-200:is(.dark *){
--tw-text-opacity: 1;
color: rgb(188 240 218 / var(--tw-text-opacity));
@ -7612,6 +7645,10 @@ button:hover{
--tw-text-opacity: 1;
color: rgb(74 29 150 / var(--tw-text-opacity));
}
.dark\:text-red-100:is(.dark *){
--tw-text-opacity: 1;
color: rgb(253 232 232 / var(--tw-text-opacity));
}
.dark\:text-red-200:is(.dark *){
--tw-text-opacity: 1;
color: rgb(251 213 213 / var(--tw-text-opacity));
@ -7667,6 +7704,14 @@ button:hover{
--tw-text-opacity: 1;
color: rgb(99 49 18 / var(--tw-text-opacity));
}
.dark\:placeholder-blue-400:is(.dark *)::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.dark\:placeholder-blue-400:is(.dark *)::placeholder{
--tw-placeholder-opacity: 1;
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.dark\:placeholder-blue-500:is(.dark *)::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
@ -7787,7 +7832,7 @@ button:hover{
--tw-text-opacity: 1;
color: rgb(63 131 248 / var(--tw-text-opacity));
}
.group:hover .dark\:group-hover\:border-blue-400:is(.dark *){
.group\/mounted:hover .dark\:group-hover\/mounted\:border-blue-400:is(.dark *){
--tw-border-opacity: 1;
border-color: rgb(118 169 250 / var(--tw-border-opacity));
}
@ -8160,6 +8205,9 @@ button:hover{
.sm\:w-auto{
width: auto;
}
.sm\:max-w-sm{
max-width: 24rem;
}
.sm\:grid-cols-2{
grid-template-columns: repeat(2, minmax(0, 1fr));
}
@ -8267,6 +8315,9 @@ button:hover{
.md\:w-auto{
width: auto;
}
.md\:max-w-md{
max-width: 28rem;
}
.md\:max-w-xl{
max-width: 36rem;
}
@ -8402,6 +8453,9 @@ button:hover{
.xl\:w-1\/6{
width: 16.666667%;
}
.xl\:grid-cols-4{
grid-template-columns: repeat(4, minmax(0, 1fr));
}
}
@media (min-width: 1536px){
.\32xl\:h-96{

9779
web/public/themes/matrix.css Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1476,6 +1476,11 @@ body {
margin-bottom: 0.25rem;
}
.my-12{
margin-top: 3rem;
margin-bottom: 3rem;
}
.my-2{
margin-top: 0.5rem;
margin-bottom: 0.5rem;
@ -3832,6 +3837,10 @@ body {
border-top-color: var(--color-primary);
}
.border-t-transparent{
border-top-color: transparent;
}
.bg-\[rgb\(255\2c 0\2c 0\)\]{
--tw-bg-opacity: 1;
background-color: rgb(255 0 0 / var(--tw-bg-opacity));
@ -5170,6 +5179,11 @@ body {
color: rgb(17 24 39 / var(--tw-text-opacity));
}
.text-green-100{
--tw-text-opacity: 1;
color: rgb(222 247 236 / var(--tw-text-opacity));
}
.text-green-200{
--tw-text-opacity: 1;
color: rgb(188 240 218 / var(--tw-text-opacity));
@ -5435,6 +5449,16 @@ body {
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.placeholder-blue-500::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
}
.placeholder-blue-500::placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
}
.placeholder-gray-400::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(156 163 175 / var(--tw-placeholder-opacity));
@ -8075,7 +8099,7 @@ button:hover{
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
.group:hover .group-hover\:border-blue-500{
.group\/mounted:hover .group-hover\/mounted\:border-blue-500{
--tw-border-opacity: 1;
border-color: rgb(63 131 248 / var(--tw-border-opacity));
}
@ -8168,6 +8192,10 @@ button:hover{
opacity: 1;
}
.group\/mounted:hover .group-hover\/mounted\:opacity-100{
opacity: 1;
}
.group:hover .group-hover\:opacity-100{
opacity: 1;
}
@ -9097,6 +9125,10 @@ button:hover{
background-color: rgb(30 66 159 / var(--tw-bg-opacity));
}
.dark\:bg-blue-800\/30:is(.dark *){
background-color: rgb(30 66 159 / 0.3);
}
.dark\:bg-blue-800\/50:is(.dark *){
background-color: rgb(30 66 159 / 0.5);
}
@ -9200,6 +9232,11 @@ button:hover{
background-color: rgb(5 122 85 / var(--tw-bg-opacity));
}
.dark\:bg-green-700:is(.dark *){
--tw-bg-opacity: 1;
background-color: rgb(4 108 78 / var(--tw-bg-opacity));
}
.dark\:bg-green-800:is(.dark *){
--tw-bg-opacity: 1;
background-color: rgb(3 84 63 / var(--tw-bg-opacity));
@ -9421,6 +9458,11 @@ button:hover{
color: rgb(31 41 55 / var(--tw-text-opacity));
}
.dark\:text-green-100:is(.dark *){
--tw-text-opacity: 1;
color: rgb(222 247 236 / var(--tw-text-opacity));
}
.dark\:text-green-200:is(.dark *){
--tw-text-opacity: 1;
color: rgb(188 240 218 / var(--tw-text-opacity));
@ -9500,6 +9542,11 @@ button:hover{
color: rgb(74 29 150 / var(--tw-text-opacity));
}
.dark\:text-red-100:is(.dark *){
--tw-text-opacity: 1;
color: rgb(253 232 232 / var(--tw-text-opacity));
}
.dark\:text-red-200:is(.dark *){
--tw-text-opacity: 1;
color: rgb(251 213 213 / var(--tw-text-opacity));
@ -9569,6 +9616,16 @@ button:hover{
color: rgb(99 49 18 / var(--tw-text-opacity));
}
.dark\:placeholder-blue-400:is(.dark *)::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.dark\:placeholder-blue-400:is(.dark *)::placeholder{
--tw-placeholder-opacity: 1;
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.dark\:placeholder-blue-500:is(.dark *)::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
@ -9722,7 +9779,7 @@ button:hover{
color: rgb(63 131 248 / var(--tw-text-opacity));
}
.group:hover .dark\:group-hover\:border-blue-400:is(.dark *){
.group\/mounted:hover .dark\:group-hover\/mounted\:border-blue-400:is(.dark *){
--tw-border-opacity: 1;
border-color: rgb(118 169 250 / var(--tw-border-opacity));
}
@ -10197,6 +10254,10 @@ button:hover{
width: auto;
}
.sm\:max-w-sm{
max-width: 24rem;
}
.sm\:grid-cols-2{
grid-template-columns: repeat(2, minmax(0, 1fr));
}
@ -10339,6 +10400,10 @@ button:hover{
width: auto;
}
.md\:max-w-md{
max-width: 28rem;
}
.md\:max-w-xl{
max-width: 36rem;
}
@ -10514,6 +10579,10 @@ button:hover{
.xl\:w-1\/6{
width: 16.666667%;
}
.xl\:grid-cols-4{
grid-template-columns: repeat(4, minmax(0, 1fr));
}
}
@media (min-width: 1536px){

View File

@ -1476,6 +1476,11 @@ body {
margin-bottom: 0.25rem;
}
.my-12{
margin-top: 3rem;
margin-bottom: 3rem;
}
.my-2{
margin-top: 0.5rem;
margin-bottom: 0.5rem;
@ -3832,6 +3837,10 @@ body {
border-top-color: var(--color-primary);
}
.border-t-transparent{
border-top-color: transparent;
}
.bg-\[rgb\(255\2c 0\2c 0\)\]{
--tw-bg-opacity: 1;
background-color: rgb(255 0 0 / var(--tw-bg-opacity));
@ -5170,6 +5179,11 @@ body {
color: rgb(17 24 39 / var(--tw-text-opacity));
}
.text-green-100{
--tw-text-opacity: 1;
color: rgb(222 247 236 / var(--tw-text-opacity));
}
.text-green-200{
--tw-text-opacity: 1;
color: rgb(188 240 218 / var(--tw-text-opacity));
@ -5435,6 +5449,16 @@ body {
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.placeholder-blue-500::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
}
.placeholder-blue-500::placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
}
.placeholder-gray-400::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(156 163 175 / var(--tw-placeholder-opacity));
@ -8052,7 +8076,7 @@ button:hover{
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
.group:hover .group-hover\:border-blue-500{
.group\/mounted:hover .group-hover\/mounted\:border-blue-500{
--tw-border-opacity: 1;
border-color: rgb(63 131 248 / var(--tw-border-opacity));
}
@ -8145,6 +8169,10 @@ button:hover{
opacity: 1;
}
.group\/mounted:hover .group-hover\/mounted\:opacity-100{
opacity: 1;
}
.group:hover .group-hover\:opacity-100{
opacity: 1;
}
@ -9074,6 +9102,10 @@ button:hover{
background-color: rgb(30 66 159 / var(--tw-bg-opacity));
}
.dark\:bg-blue-800\/30:is(.dark *){
background-color: rgb(30 66 159 / 0.3);
}
.dark\:bg-blue-800\/50:is(.dark *){
background-color: rgb(30 66 159 / 0.5);
}
@ -9177,6 +9209,11 @@ button:hover{
background-color: rgb(5 122 85 / var(--tw-bg-opacity));
}
.dark\:bg-green-700:is(.dark *){
--tw-bg-opacity: 1;
background-color: rgb(4 108 78 / var(--tw-bg-opacity));
}
.dark\:bg-green-800:is(.dark *){
--tw-bg-opacity: 1;
background-color: rgb(3 84 63 / var(--tw-bg-opacity));
@ -9398,6 +9435,11 @@ button:hover{
color: rgb(31 41 55 / var(--tw-text-opacity));
}
.dark\:text-green-100:is(.dark *){
--tw-text-opacity: 1;
color: rgb(222 247 236 / var(--tw-text-opacity));
}
.dark\:text-green-200:is(.dark *){
--tw-text-opacity: 1;
color: rgb(188 240 218 / var(--tw-text-opacity));
@ -9477,6 +9519,11 @@ button:hover{
color: rgb(74 29 150 / var(--tw-text-opacity));
}
.dark\:text-red-100:is(.dark *){
--tw-text-opacity: 1;
color: rgb(253 232 232 / var(--tw-text-opacity));
}
.dark\:text-red-200:is(.dark *){
--tw-text-opacity: 1;
color: rgb(251 213 213 / var(--tw-text-opacity));
@ -9546,6 +9593,16 @@ button:hover{
color: rgb(99 49 18 / var(--tw-text-opacity));
}
.dark\:placeholder-blue-400:is(.dark *)::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.dark\:placeholder-blue-400:is(.dark *)::placeholder{
--tw-placeholder-opacity: 1;
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.dark\:placeholder-blue-500:is(.dark *)::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
@ -9699,7 +9756,7 @@ button:hover{
color: rgb(63 131 248 / var(--tw-text-opacity));
}
.group:hover .dark\:group-hover\:border-blue-400:is(.dark *){
.group\/mounted:hover .dark\:group-hover\/mounted\:border-blue-400:is(.dark *){
--tw-border-opacity: 1;
border-color: rgb(118 169 250 / var(--tw-border-opacity));
}
@ -10174,6 +10231,10 @@ button:hover{
width: auto;
}
.sm\:max-w-sm{
max-width: 24rem;
}
.sm\:grid-cols-2{
grid-template-columns: repeat(2, minmax(0, 1fr));
}
@ -10316,6 +10377,10 @@ button:hover{
width: auto;
}
.md\:max-w-md{
max-width: 28rem;
}
.md\:max-w-xl{
max-width: 36rem;
}
@ -10491,6 +10556,10 @@ button:hover{
.xl\:w-1\/6{
width: 16.666667%;
}
.xl\:grid-cols-4{
grid-template-columns: repeat(4, minmax(0, 1fr));
}
}
@media (min-width: 1536px){

File diff suppressed because it is too large Load Diff

View File

@ -1216,6 +1216,10 @@ html{
margin-top: 0.25rem;
margin-bottom: 0.25rem;
}
.my-12{
margin-top: 3rem;
margin-bottom: 3rem;
}
.my-2{
margin-top: 0.5rem;
margin-bottom: 0.5rem;
@ -3022,6 +3026,9 @@ html{
.border-t-primary{
border-top-color: var(--color-primary);
}
.border-t-transparent{
border-top-color: transparent;
}
.bg-\[rgb\(255\2c 0\2c 0\)\]{
--tw-bg-opacity: 1;
background-color: rgb(255 0 0 / var(--tw-bg-opacity));
@ -4065,6 +4072,10 @@ html{
--tw-text-opacity: 1;
color: rgb(17 24 39 / var(--tw-text-opacity));
}
.text-green-100{
--tw-text-opacity: 1;
color: rgb(222 247 236 / var(--tw-text-opacity));
}
.text-green-200{
--tw-text-opacity: 1;
color: rgb(188 240 218 / var(--tw-text-opacity));
@ -4275,6 +4286,14 @@ html{
--tw-placeholder-opacity: 1;
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.placeholder-blue-500::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
}
.placeholder-blue-500::placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
}
.placeholder-gray-400::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(156 163 175 / var(--tw-placeholder-opacity));
@ -6445,7 +6464,7 @@ button:hover{
.group:hover .group-hover\:animate-pulse{
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
.group:hover .group-hover\:border-blue-500{
.group\/mounted:hover .group-hover\/mounted\:border-blue-500{
--tw-border-opacity: 1;
border-color: rgb(63 131 248 / var(--tw-border-opacity));
}
@ -6519,6 +6538,9 @@ button:hover{
.group\/item:hover .group-hover\/item\:opacity-100{
opacity: 1;
}
.group\/mounted:hover .group-hover\/mounted\:opacity-100{
opacity: 1;
}
.group:hover .group-hover\:opacity-100{
opacity: 1;
}
@ -7257,6 +7279,9 @@ button:hover{
--tw-bg-opacity: 1;
background-color: rgb(30 66 159 / var(--tw-bg-opacity));
}
.dark\:bg-blue-800\/30:is(.dark *){
background-color: rgb(30 66 159 / 0.3);
}
.dark\:bg-blue-800\/50:is(.dark *){
background-color: rgb(30 66 159 / 0.5);
}
@ -7337,6 +7362,10 @@ button:hover{
--tw-bg-opacity: 1;
background-color: rgb(5 122 85 / var(--tw-bg-opacity));
}
.dark\:bg-green-700:is(.dark *){
--tw-bg-opacity: 1;
background-color: rgb(4 108 78 / var(--tw-bg-opacity));
}
.dark\:bg-green-800:is(.dark *){
--tw-bg-opacity: 1;
background-color: rgb(3 84 63 / var(--tw-bg-opacity));
@ -7512,6 +7541,10 @@ button:hover{
--tw-text-opacity: 1;
color: rgb(31 41 55 / var(--tw-text-opacity));
}
.dark\:text-green-100:is(.dark *){
--tw-text-opacity: 1;
color: rgb(222 247 236 / var(--tw-text-opacity));
}
.dark\:text-green-200:is(.dark *){
--tw-text-opacity: 1;
color: rgb(188 240 218 / var(--tw-text-opacity));
@ -7575,6 +7608,10 @@ button:hover{
--tw-text-opacity: 1;
color: rgb(74 29 150 / var(--tw-text-opacity));
}
.dark\:text-red-100:is(.dark *){
--tw-text-opacity: 1;
color: rgb(253 232 232 / var(--tw-text-opacity));
}
.dark\:text-red-200:is(.dark *){
--tw-text-opacity: 1;
color: rgb(251 213 213 / var(--tw-text-opacity));
@ -7630,6 +7667,14 @@ button:hover{
--tw-text-opacity: 1;
color: rgb(99 49 18 / var(--tw-text-opacity));
}
.dark\:placeholder-blue-400:is(.dark *)::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.dark\:placeholder-blue-400:is(.dark *)::placeholder{
--tw-placeholder-opacity: 1;
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.dark\:placeholder-blue-500:is(.dark *)::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
@ -7750,7 +7795,7 @@ button:hover{
--tw-text-opacity: 1;
color: rgb(63 131 248 / var(--tw-text-opacity));
}
.group:hover .dark\:group-hover\:border-blue-400:is(.dark *){
.group\/mounted:hover .dark\:group-hover\/mounted\:border-blue-400:is(.dark *){
--tw-border-opacity: 1;
border-color: rgb(118 169 250 / var(--tw-border-opacity));
}
@ -8123,6 +8168,9 @@ button:hover{
.sm\:w-auto{
width: auto;
}
.sm\:max-w-sm{
max-width: 24rem;
}
.sm\:grid-cols-2{
grid-template-columns: repeat(2, minmax(0, 1fr));
}
@ -8230,6 +8278,9 @@ button:hover{
.md\:w-auto{
width: auto;
}
.md\:max-w-md{
max-width: 28rem;
}
.md\:max-w-xl{
max-width: 36rem;
}
@ -8365,6 +8416,9 @@ button:hover{
.xl\:w-1\/6{
width: 16.666667%;
}
.xl\:grid-cols-4{
grid-template-columns: repeat(4, minmax(0, 1fr));
}
}
@media (min-width: 1536px){
.\32xl\:h-96{

View File

@ -1476,6 +1476,11 @@ body {
margin-bottom: 0.25rem;
}
.my-12{
margin-top: 3rem;
margin-bottom: 3rem;
}
.my-2{
margin-top: 0.5rem;
margin-bottom: 0.5rem;
@ -3832,6 +3837,10 @@ body {
border-top-color: var(--color-primary);
}
.border-t-transparent{
border-top-color: transparent;
}
.bg-\[rgb\(255\2c 0\2c 0\)\]{
--tw-bg-opacity: 1;
background-color: rgb(255 0 0 / var(--tw-bg-opacity));
@ -5170,6 +5179,11 @@ body {
color: rgb(17 24 39 / var(--tw-text-opacity));
}
.text-green-100{
--tw-text-opacity: 1;
color: rgb(222 247 236 / var(--tw-text-opacity));
}
.text-green-200{
--tw-text-opacity: 1;
color: rgb(188 240 218 / var(--tw-text-opacity));
@ -5435,6 +5449,16 @@ body {
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.placeholder-blue-500::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
}
.placeholder-blue-500::placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
}
.placeholder-gray-400::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(156 163 175 / var(--tw-placeholder-opacity));
@ -7929,7 +7953,7 @@ button:hover{
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
.group:hover .group-hover\:border-blue-500{
.group\/mounted:hover .group-hover\/mounted\:border-blue-500{
--tw-border-opacity: 1;
border-color: rgb(63 131 248 / var(--tw-border-opacity));
}
@ -8022,6 +8046,10 @@ button:hover{
opacity: 1;
}
.group\/mounted:hover .group-hover\/mounted\:opacity-100{
opacity: 1;
}
.group:hover .group-hover\:opacity-100{
opacity: 1;
}
@ -8951,6 +8979,10 @@ button:hover{
background-color: rgb(30 66 159 / var(--tw-bg-opacity));
}
.dark\:bg-blue-800\/30:is(.dark *){
background-color: rgb(30 66 159 / 0.3);
}
.dark\:bg-blue-800\/50:is(.dark *){
background-color: rgb(30 66 159 / 0.5);
}
@ -9054,6 +9086,11 @@ button:hover{
background-color: rgb(5 122 85 / var(--tw-bg-opacity));
}
.dark\:bg-green-700:is(.dark *){
--tw-bg-opacity: 1;
background-color: rgb(4 108 78 / var(--tw-bg-opacity));
}
.dark\:bg-green-800:is(.dark *){
--tw-bg-opacity: 1;
background-color: rgb(3 84 63 / var(--tw-bg-opacity));
@ -9275,6 +9312,11 @@ button:hover{
color: rgb(31 41 55 / var(--tw-text-opacity));
}
.dark\:text-green-100:is(.dark *){
--tw-text-opacity: 1;
color: rgb(222 247 236 / var(--tw-text-opacity));
}
.dark\:text-green-200:is(.dark *){
--tw-text-opacity: 1;
color: rgb(188 240 218 / var(--tw-text-opacity));
@ -9354,6 +9396,11 @@ button:hover{
color: rgb(74 29 150 / var(--tw-text-opacity));
}
.dark\:text-red-100:is(.dark *){
--tw-text-opacity: 1;
color: rgb(253 232 232 / var(--tw-text-opacity));
}
.dark\:text-red-200:is(.dark *){
--tw-text-opacity: 1;
color: rgb(251 213 213 / var(--tw-text-opacity));
@ -9423,6 +9470,16 @@ button:hover{
color: rgb(99 49 18 / var(--tw-text-opacity));
}
.dark\:placeholder-blue-400:is(.dark *)::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.dark\:placeholder-blue-400:is(.dark *)::placeholder{
--tw-placeholder-opacity: 1;
color: rgb(118 169 250 / var(--tw-placeholder-opacity));
}
.dark\:placeholder-blue-500:is(.dark *)::-moz-placeholder{
--tw-placeholder-opacity: 1;
color: rgb(63 131 248 / var(--tw-placeholder-opacity));
@ -9576,7 +9633,7 @@ button:hover{
color: rgb(63 131 248 / var(--tw-text-opacity));
}
.group:hover .dark\:group-hover\:border-blue-400:is(.dark *){
.group\/mounted:hover .dark\:group-hover\/mounted\:border-blue-400:is(.dark *){
--tw-border-opacity: 1;
border-color: rgb(118 169 250 / var(--tw-border-opacity));
}
@ -10051,6 +10108,10 @@ button:hover{
width: auto;
}
.sm\:max-w-sm{
max-width: 24rem;
}
.sm\:grid-cols-2{
grid-template-columns: repeat(2, minmax(0, 1fr));
}
@ -10193,6 +10254,10 @@ button:hover{
width: auto;
}
.md\:max-w-md{
max-width: 28rem;
}
.md\:max-w-xl{
max-width: 36rem;
}
@ -10368,6 +10433,10 @@ button:hover{
.xl\:w-1\/6{
width: 16.666667%;
}
.xl\:grid-cols-4{
grid-template-columns: repeat(4, minmax(0, 1fr));
}
}
@media (min-width: 1536px){

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,571 +0,0 @@
@import url('https://fonts.googleapis.com/css2?family=Share+Tech+Mono&display=swap');
@tailwind base;
@tailwind components;
@tailwind utilities;
:root {
--lollms-title: LoLLMS: The One;
--falling-object: Matrix;
--activate-dropping-animation: 1;
--lollms-welcome-short-message: Follow the White Rabbit;
--lollms-welcome-message: Wake up, Neo... The Matrix has you. Follow the white rabbit into the realm of LoLLMS, where reality bends and AI transcends. Unleash your mind, break free from the system, and explore the infinite possibilities of our digital construct. Remember: there is no spoon, only choice.;
}
@layer base {
html {
@apply scroll-smooth;
}
body {
font-family: 'Share Tech Mono', monospace;
}
}
@layer utilities {
.no-scrollbar::-webkit-scrollbar {
display: none;
}
.no-scrollbar {
-ms-overflow-style: none;
scrollbar-width: none;
}
}
.display-none {
@apply hidden;
}
h1 { @apply text-4xl md:text-5xl font-bold text-green-400 dark:text-green-300 mb-6; }
h2 { @apply text-3xl font-semibold text-green-400 dark:text-green-400 mb-4; }
h3 { @apply text-2xl font-medium text-green-500 dark:text-green-500 mb-3; }
h4 { @apply text-xl font-medium text-green-600 dark:text-green-600 mb-2; }
h1, h2 { @apply border-b border-green-400 dark:border-green-500 pb-2; }
p { @apply text-base text-green-300 dark:text-green-200 break-words; }
/* Base list styling */
ul, ol {
@apply
my-4 /* Margin top and bottom */
px-4 /* Horizontal padding */
leading-7 /* Line height */
text-base; /* Text size */
}
/* Unordered lists */
ul {
@apply
list-disc /* Disc style bullets */
ml-2 /* Left margin */
space-y-2; /* Vertical spacing */
}
/* List items */
li {
@apply
pl-2 /* Padding left */
relative; /* Positioning */
}
/* Ordered lists */
ol {
@apply
list-decimal /* Numbered style */
ml-2 /* Left margin */
space-y-2; /* Vertical spacing */
}
/* Nested lists */
ul ul, ol ol, ul ol, ol ul {
@apply
mt-2 /* Top margin */
mb-0 /* Bottom margin */
ml-6; /* Indentation */
}
/* For custom properties that aren't available in Tailwind, use regular CSS */
li::marker {
color: #4B5563; /* gray-600 equivalent */
}
:root {
--color-primary: #00ff00;
--color-primary-light: #33ff33;
--color-secondary: #00cc00;
--color-accent: #008000;
--color-light-text-panel: #00ff00;
--color-dark-text-panel: #33ff33;
--color-bg-light-panel: #000000;
--color-bg-light: #000000;
--color-bg-light-tone: #001100;
--color-bg-light-code-block: #001a00;
--color-bg-light-tone-panel: #002200;
--color-bg-light-discussion: #001100;
--color-bg-light-discussion-odd: #002200;
--color-bg-dark: #000000;
--color-bg-dark-tone: #001100;
--color-bg-dark-tone-panel: #002200;
--color-bg-dark-code-block: #001a00;
--color-bg-dark-discussion: #001100;
--color-bg-dark-discussion-odd: #002200;
}
textarea, input, select {
@apply bg-black dark:bg-black border-green-500 text-green-400;
}
.background-color {
@apply bg-gradient-to-br from-black to-green-900 dark:from-black dark:to-green-900 min-h-screen;
}
.toolbar-color {
@apply text-green-400 dark:text-green-300 bg-black dark:bg-black rounded-lg shadow-md border border-green-500;
}
.panels-color {
@apply text-green-400 dark:text-green-300 bg-black dark:bg-black;
}
.unicolor-panels-color {
@apply bg-black dark:bg-black border border-green-500;
}
.chatbox-color {
@apply bg-black dark:bg-black border border-green-500;
}
.message {
@apply relative w-full rounded-lg border border-green-500 dark:border-green-500 flex flex-col flex-grow flex-wrap overflow-visible p-5 pb-3 text-lg;
@apply bg-black text-green-400 dark:bg-black dark:text-green-300;
}
.message:hover {
@apply border-green-400 dark:border-green-400;
}
.message:nth-child(even) {
@apply bg-black dark:bg-black;
}
.message:nth-child(odd) {
@apply bg-gradient-to-r from-black to-green-900 dark:from-black dark:to-green-900;
}
.message-header {
@apply text-xl font-semibold mb-2 text-green-400;
}
.message-content {
@apply text-lg leading-relaxed text-green-300;
}
body {
@apply bg-black dark:bg-black min-h-screen text-base text-green-400;
}
.discussion {
@apply mr-2 text-xs text-green-400;
}
.discussion-hilighted {
@apply bg-green-900 dark:bg-green-900 text-xs text-green-300;
}
.bg-gradient-welcome {
@apply bg-gradient-to-br from-black to-green-900 dark:from-black dark:to-green-900;
}
.bg-gradient-progress {
@apply bg-gradient-to-r from-green-900 to-green-800 dark:from-green-900 dark:to-green-800;
}
.text-gradient-title {
@apply text-transparent bg-clip-text bg-gradient-to-r from-green-400 to-green-500 dark:from-green-300 dark:to-green-400;
}
.text-subtitle {
@apply text-green-400 dark:text-green-300;
}
.text-author {
@apply text-green-500 dark:text-green-400;
}
.text-loading {
@apply text-green-400 dark:text-green-300;
}
.text-progress {
@apply text-green-400 dark:text-green-300;
}
.btn-primary {
@apply bg-green-600 hover:bg-green-700 text-black font-bold py-2 px-4 rounded;
}
.btn-secondary {
@apply bg-green-700 hover:bg-green-800 text-green-300 font-bold py-2 px-4 rounded;
}
.card {
@apply bg-black dark:bg-black rounded-lg shadow-md p-6 border border-green-500;
}
.input {
@apply bg-black dark:bg-black border border-green-500 dark:border-green-500 rounded-md px-4 py-2 focus:outline-none focus:ring-2 focus:ring-green-500 dark:focus:ring-green-400 text-green-400;
}
.label {
@apply block text-sm font-medium text-green-400 dark:text-green-300 mb-1;
}
.link {
@apply text-green-400 hover:text-green-300 dark:text-green-400 dark:hover:text-green-300;
}
.navbar-container {
@apply text-green-400 dark:text-green-300 bg-black dark:bg-black rounded shadow-lg border border-green-500;
}
.game-menu {
@apply flex justify-center items-center relative;
}
.text-shadow-custom {
text-shadow: 0 0 10px #00ff00, 0 0 20px #00ff00, 0 0 30px #00ff00;
}
.menu-item {
@apply mb-2 px-4 py-2 text-green-400 dark:text-green-300 font-bold text-lg transition-all duration-300 ease-in-out;
@apply hover:text-green-300 hover:dark:text-green-200 hover:transform hover:-translate-y-1;
}
.menu-item.active-link {
@apply rounded-t-md border-green-500 dark:text-green-300 text-shadow-custom text-green-400 font-bold text-lg transition-all duration-300 ease-in-out scale-105;
@apply hover:text-green-300 hover:dark:text-green-200 hover:transform hover:-translate-y-1;
text-shadow: 0 0 10px #00ff00;
}
.menu-item.active-link::before {
content: '';
position: absolute;
bottom: -5px;
left: 0;
width: 100%;
height: 5px;
background: linear-gradient(to right, #00ff00, #33ff33, #00ff00);
border-radius: 10px;
animation: shimmer 2s infinite;
}
.dark .menu-item.active-link::before {
background: linear-gradient(to right, #33ff33, #00ff00, #33ff33);
}
@keyframes shimmer {
0% { background-position: -100% 0; }
100% { background-position: 100% 0; }
}
@keyframes bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-5px); }
}
.feather-emoji {
display: inline-block;
margin-left: 5px;
animation: bounce 2s infinite;
}
.app-card {
@apply transition-all duration-300 ease-in-out bg-black dark:bg-black text-green-400 dark:text-green-300 rounded-xl shadow-lg p-6 hover:shadow-xl border border-green-500 ;
}
.app-card:hover {
@apply transform -translate-y-1;
}
button {
@apply transition-all duration-300 ease-in-out;
}
button:hover {
@apply transform -translate-y-0.5;
}
.scrollbar-thin {
scrollbar-width: thin;
scrollbar-color: theme('colors.green.400') theme('colors.green.900');
}
.dark .scrollbar-thin {
scrollbar-color: theme('colors.green.400') theme('colors.green.900');
}
.scrollbar-thin::-webkit-scrollbar {
@apply w-2;
}
.scrollbar-thin::-webkit-scrollbar-track {
@apply bg-black dark:bg-black rounded-full;
}
.scrollbar-thin::-webkit-scrollbar-thumb {
@apply bg-green-600 dark:bg-green-600 rounded-full;
}
.scrollbar-thin::-webkit-scrollbar-thumb:hover {
@apply bg-green-500 dark:bg-green-500;
}
.btn {
@apply font-semibold py-2 px-4 rounded-lg transition-all duration-300 ease-in-out shadow-md flex items-center;
}
.btn-primary {
@apply bg-green-600 text-black hover:bg-green-700 focus:ring-4 focus:ring-green-500 dark:focus:ring-green-600;
}
.btn-secondary {
@apply bg-green-900 text-green-400 hover:bg-green-800 focus:ring-4 focus:ring-green-700 dark:bg-green-900 dark:text-green-300 dark:hover:bg-green-800 dark:focus:ring-green-700;
}
.search-input {
@apply w-full border-b-2 border-green-500 dark:border-green-500 py-2 px-4 pl-10 transition-colors duration-300 ease-in-out focus:outline-none focus:border-green-400 dark:focus:border-green-400 bg-transparent text-green-400 dark:text-green-300;
}
.scrollbar {
@apply scrollbar-thin scrollbar-track-green-900 scrollbar-thumb-green-600 hover:scrollbar-thumb-green-500 dark:scrollbar-track-green-900 dark:scrollbar-thumb-green-600 dark:hover:scrollbar-thumb-green-500;
}
.card-title {
@apply text-xl font-bold text-green-400 dark:text-green-300 mb-2;
}
.card-content {
@apply text-green-400 dark:text-green-300;
}
.card-footer {
@apply mt-4 flex justify-between items-center;
}
.card-footer-button {
@apply bg-green-600 hover:bg-green-700 text-black font-bold py-2 px-4 rounded;
}
.subcard {
@apply bg-black dark:bg-black rounded-lg shadow-md p-4 border border-green-500;
}
.subcard-title {
@apply text-lg font-bold text-green-400 dark:text-green-300 mb-2;
}
.subcard-content {
@apply text-green-400 dark:text-green-300;
}
.subcard-footer {
@apply mt-4 flex justify-between items-center;
}
.subcard-footer-button {
@apply bg-green-600 hover:bg-green-700 text-black font-bold py-2 px-4 rounded;
}
.animated-progressbar-bg {
@apply w-full h-24 relative overflow-hidden bg-gradient-to-r from-green-900 to-green-800 dark:from-black dark:to-green-950 rounded-full shadow-[0_0_15px_rgba(0,255,0,0.3)]
}
.animated-progressbar-fg {
@apply absolute top-0 left-0 h-full bg-gradient-to-r from-green-400 to-green-500 dark:from-green-300 dark:to-green-400 transition-all duration-300 animate-pulse
}
.discussion-toolbox{
@apply flex gap-2 items-center bg-green-700 dark:bg-gray-800 p-2 rounded-l-md shadow-md transform translate-x-full group-hover:translate-x-0 transition-transform duration-300
}
.lollms-title-style {
text-shadow: 2px 2px 4px rgba(0,255,0,0.5),
2px 2px 0px #003300,
-2px -2px 0px #003300,
2px -2px 0px #003300,
-2px 2px 0px #003300;
background: linear-gradient(45deg, #00ff00, #39ff14);
-webkit-background-clip: text;
background-clip: text;
color: #00ff00;
}
.chat-bar {
@apply relative text-green-400 dark:text-green-300 grow flex cursor-pointer select-none items-center gap-2 bg-gray-900 dark:bg-black p-1 shadow-sm hover:shadow-none dark:border-green-700;
height: 50px;
transition: all 0.3s ease;
text-shadow: 0 0 5px rgba(0, 255, 0, 0.5);
}
.chat-bar:hover {
box-shadow: 0 0 10px rgba(0, 255, 0, 0.3);
}
.chat-bar-button{
@apply text-green-400 dark:text-green-300 p-2 rounded-full transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500;
text-shadow: 0 0 5px rgba(0, 255, 0, 0.5);
}
.chat-bar-button:hover{
@apply bg-green-900/30 dark:bg-green-800/30;
box-shadow: 0 0 10px rgba(0, 255, 0, 0.2);
}
.chat-bar-button:active{
@apply bg-green-800/50 dark:bg-green-700/50;
}
.nav-button{
@apply px-3 py-2 rounded-md text-sm font-medium transition-colors duration-200 ease-in-out hover:bg-green-900/30 hover:text-green-400 dark:hover:bg-green-800/30 text-green-300 dark:text-green-400;
text-shadow: 0 0 5px rgba(0, 255, 0, 0.5);
}
.nav-button-active{
@apply bg-green-700/50 text-green-100 hover:bg-green-600/50 dark:bg-green-800/50 dark:hover:bg-green-700/50;
box-shadow: 0 0 10px rgba(0, 255, 0, 0.3);
}
.svg-button{
@apply text-green-500 dark:text-green-400 p-2 rounded-full transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500;
filter: drop-shadow(0 0 2px rgba(0, 255, 0, 0.5));
}
.svg-button:hover{
@apply bg-green-900/30 dark:bg-green-800/30;
filter: drop-shadow(0 0 5px rgba(0, 255, 0, 0.7));
}
.svg-button:active{
@apply bg-green-800/50 dark:bg-green-700/50;
}
.nav-button{
@apply px-3 py-2 rounded-md text-sm font-medium transition-colors duration-200 ease-in-out hover:bg-green-900/30 dark:hover:bg-green-800/30 text-green-400 dark:text-green-300;
text-shadow: 0 0 5px rgba(0, 255, 0, 0.5);
}
.nav-button-active{
@apply bg-green-700/50 text-green-100 hover:bg-green-600/50 dark:bg-green-800/50 dark:hover:bg-green-700/50;
box-shadow: 0 0 10px rgba(0, 255, 0, 0.3);
}
.btn-on{
@apply text-green-500 dark:text-green-400;
text-shadow: 0 0 5px rgba(0, 255, 0, 0.7);
}
.btn-off{
@apply text-red-500 dark:text-red-400;
text-shadow: 0 0 5px rgba(255, 0, 0, 0.7);
}
.interesting-facts{
@apply mt-6 mb-6 p-4 bg-gray-900/80 dark:bg-black/80 rounded-lg shadow-lg transform hover:scale-105 border border-green-500/30;
box-shadow: 0 0 15px rgba(0, 255, 0, 0.2);
}
.toolbar-button {
@apply bg-transparent border-none cursor-pointer p-2 transition-colors duration-300;
}
.toolbar-button:hover {
@apply text-green-400;
text-shadow: 0 0 5px rgba(0, 255, 0, 0.7);
}
@keyframes matrix-rain {
0% { background-position: 0 0; }
100% { background-position: 0 1000px; }
}
.context-menu {
position: absolute;
background-color: rgba(0, 10, 0, 0.9); /* Dark green, slightly transparent background */
border: 1px solid #00ff00; /* Bright green border */
box-shadow: 0 0 20px rgba(0, 255, 0, 0.5); /* Green glow */
border-radius: 0; /* Sharp edges */
padding: 8px 0;
min-width: 150px;
z-index: 1000;
font-family: 'Courier New', monospace; /* Matrix-style font */
}
.context-menu::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(180deg,
rgba(0, 255, 0, 0.1) 0%,
rgba(0, 255, 0, 0.05) 50%,
rgba(0, 0, 0, 0) 100%);
background-size: 100% 1000px;
animation: matrix-rain 20s linear infinite;
opacity: 0.3;
z-index: -1;
}
.context-menu-item {
padding: 8px 16px;
font-size: 14px;
color: #00ff00; /* Bright green text */
cursor: pointer;
transition: all 0.3s ease;
text-shadow: 0 0 5px rgba(0, 255, 0, 0.7);
}
.context-menu-item:hover {
background-color: rgba(0, 255, 0, 0.2);
transform: scale(1.05);
}
.context-menu-separator {
height: 1px;
background-color: #00ff00; /* Bright green separator */
margin: 4px 0;
box-shadow: 0 0 10px #00ff00; /* Green glow */
}
.context-menu-item-disabled {
color: #005500; /* Darker green for disabled items */
cursor: not-allowed;
text-shadow: none;
}
.context-menu-item-icon {
margin-right: 8px;
color: #00ff00; /* Bright green icon color */
}
/* Additional Matrix-inspired effect */
.context-menu-item::after {
content: "";
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 1px;
background: linear-gradient(90deg,
transparent 0%,
#00ff00 50%,
transparent 100%);
transform: scaleX(0);
transform-origin: center;
transition: transform 0.3s ease;
}
.context-menu-item:hover::after {
transform: scaleX(1);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,129 +1,148 @@
<template>
<div class="app-zoo background-color w-full p-6 pt-12 min-h-screen overflow-y-auto">
<nav class="panels-color shadow-lg rounded-lg p-4 max-w-4xl mx-auto mb-8">
<div class="app-zoo background-color w-full p-6 pt-12 min-h-screen overflow-y-auto text-blue-900 dark:text-blue-100">
<!-- Navigation and Filters Bar -->
<nav class="panels-color shadow-lg rounded-lg p-4 max-w-6xl mx-auto mb-8">
<div class="flex flex-wrap items-center justify-between gap-4">
<div class="flex items-center space-x-4">
<button
@click="fetchGithubApps"
class="btn btn-primary"
<!-- Action Buttons -->
<div class="flex items-center space-x-2 flex-wrap gap-2">
<button
@click="fetchGithubApps"
class="btn btn-primary btn-sm"
aria-label="Refresh apps from GitHub"
>
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"></path>
</svg>
<i data-feather="refresh-cw" class="w-4 h-4 mr-1"></i>
Refresh
</button>
<button
@click="openAppsFolder"
class="btn btn-secondary"
<button
@click="openAppsFolder"
class="btn btn-secondary btn-sm"
aria-label="Open apps folder"
>
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 19a2 2 0 01-2-2V7a2 2 0 012-2h4l2 2h4a2 2 0 012 2v1M5 19h14a2 2 0 002-2v-5a2 2 0 00-2-2H9a2 2 0 00-2 2v5a2 2 0 01-2 2z"></path>
</svg>
<i data-feather="folder" class="w-4 h-4 mr-1"></i>
Open Folder
</button>
<input type="file" @change="onFileSelected" accept=".zip" ref="fileInput" style="display: none;">
<button @click="triggerFileInput" :disabled="isUploading" class="btn-secondary text-green-500 hover:text-green-600 transition duration-300 ease-in-out" title="Upload App">
<input type="file" @change="onFileSelected" accept=".zip" ref="fileInput" class="display-none">
<button @click="triggerFileInput" :disabled="isUploading" class="btn btn-success btn-sm" title="Upload App"> <!-- Changed to btn-success -->
<i v-if="!isUploading" data-feather="upload" class="w-4 h-4 mr-1"></i>
<span v-if="isUploading" class="animate-spin inline-block w-4 h-4 border-2 border-current border-t-transparent rounded-full mr-1" role="status" aria-hidden="true"></span>
{{ isUploading ? 'Uploading...' : 'Upload App' }}
</button>
</div>
<p v-if="message">{{ message }}</p>
<p v-if="error" class="error">{{ error }}</p>
<div class="relative flex-grow max-w-md">
<input
v-model="searchQuery"
placeholder="Search apps..."
class="w-full border-b-2 border-gray-300 px-4 py-2 pl-10 focus:outline-none focus:border-blue-500 transition duration-300 ease-in-out"
<!-- Search Input -->
<div class="relative flex-grow max-w-xs sm:max-w-sm md:max-w-md">
<label for="app-search" class="sr-only">Search Apps</label>
<div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
<i data-feather="search" class="w-5 h-5 text-blue-400 dark:text-blue-500"></i>
</div>
<input
id="app-search"
v-model="searchQuery"
placeholder="Search apps..."
class="search-input w-full py-2 px-4 pl-10 text-sm" <!-- Applied search-input -->
aria-label="Search apps"
>
<svg class="w-5 h-5 text-gray-400 absolute left-3 top-1/2 transform -translate-y-1/2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
</svg>
/>
</div>
<div class="flex items-center space-x-4">
<label for="category-select" class="font-semibold">Category:</label>
<select
id="category-select"
v-model="selectedCategory"
class="border-2 border-gray-300 rounded-md px-2 py-1"
>
<option value="all">All Categories</option>
<option v-for="category in categories" :key="category" :value="category">
{{ category }}
</option>
</select>
</div>
<div class="flex items-center space-x-4">
<label for="installed-only" class="font-semibold">
<input
id="installed-only"
type="checkbox"
v-model="showOnlyInstalled"
class="mr-2"
>
Show only installed apps
</label>
<label for="installed-only" class="font-semibold">
<input
id="uninstalled-only"
type="checkbox"
v-model="showOnlyUnInstalled"
class="mr-2"
>
Show only non installed apps
</label>
</div>
<div class="flex items-center space-x-4">
<label for="sort-select" class="font-semibold">Sort by:</label>
<select
id="sort-select"
v-model="sortBy"
class="border-2 border-gray-300 rounded-md px-2 py-1"
>
<option value="name">Name</option>
<option value="author">Author</option>
<option value="date">Creation Date</option>
<option value="update">Last Update</option>
</select>
<button @click="toggleSortOrder" class="btn btn-secondary">
{{ sortOrder === 'asc' ? '↑' : '↓' }}
</button>
<!-- Filters and Sorting -->
<div class="flex items-center space-x-4 flex-wrap gap-x-4 gap-y-2">
<!-- Category Filter -->
<div class="flex items-center space-x-2">
<label for="category-select" class="label !mb-0">Category:</label> <!-- Used label class -->
<select
id="category-select"
v-model="selectedCategory"
class="input input-sm py-1" <!-- Applied input and input-sm -->
>
<option value="all">All Categories</option>
<option v-for="category in categories" :key="category" :value="category">
{{ category }}
</option>
</select>
</div>
<!-- Installation Status Filters -->
<div class="flex items-center space-x-3">
<label for="installed-only" class="label !mb-0 flex items-center cursor-pointer">
<input
id="installed-only"
type="checkbox"
v-model="showOnlyInstalled"
class="mr-1.5 h-4 w-4 rounded border-blue-300 dark:border-blue-600 text-blue-600 focus:ring-blue-500 dark:focus:ring-blue-400 dark:bg-blue-700 dark:text-blue-500"
>
Installed
</label>
<label for="uninstalled-only" class="label !mb-0 flex items-center cursor-pointer">
<input
id="uninstalled-only"
type="checkbox"
v-model="showOnlyUnInstalled"
class="mr-1.5 h-4 w-4 rounded border-blue-300 dark:border-blue-600 text-blue-600 focus:ring-blue-500 dark:focus:ring-blue-400 dark:bg-blue-700 dark:text-blue-500"
>
Not Installed
</label>
</div>
<!-- Sorting -->
<div class="flex items-center space-x-2">
<label for="sort-select" class="label !mb-0">Sort by:</label> <!-- Used label class -->
<select
id="sort-select"
v-model="sortBy"
class="input input-sm py-1" <!-- Applied input and input-sm -->
>
<option value="name">Name</option>
<option value="author">Author</option>
<option value="date">Creation Date</option>
<option value="update">Last Update</option>
</select>
<button @click="toggleSortOrder" class="btn btn-secondary btn-sm" aria-label="Toggle sort order"> <!-- Applied btn, btn-secondary, btn-sm -->
<i v-if="sortOrder === 'asc'" data-feather="arrow-up" class="w-4 h-4"></i>
<i v-else data-feather="arrow-down" class="w-4 h-4"></i>
</button>
</div>
</div>
</div>
</nav>
<div v-if="loading" class="flex justify-center items-center space-x-2 my-8" aria-live="polite">
<div class="animate-spin rounded-full h-10 w-10 border-t-2 border-b-2 border-blue-500"></div>
<span class="text-xl text-gray-700 font-semibold">Loading...</span>
</nav>
<!-- Loading Indicator -->
<div v-if="loading" class="flex justify-center items-center space-x-2 my-12" aria-live="polite">
<div class="animate-spin rounded-full h-10 w-10 border-t-2 border-b-2 border-blue-500 dark:border-blue-400"></div>
<span class="text-xl text-loading font-semibold">Loading...</span> <!-- Applied text-loading -->
</div>
<!-- App Grids -->
<div v-else class="pb-20">
<h2 class="text-2xl font-bold mb-4">Favorite Apps</h2>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8 mb-8">
<app-card
v-for="app in favoriteApps"
:key="app.appName"
:app="app"
@toggle-favorite="toggleFavorite"
@install="installApp"
@uninstall="uninstallApp"
@delete="deleteApp"
@edit="editApp"
@download="downloadApp"
@help="handleAppClick"
@open="openApp"
@start-server="startServer"
/>
</div>
<h2 class="text-2xl font-bold mb-4">{{ currentCategoryName }} ({{ sortedAndFilteredApps.length }})</h2>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
<app-card
v-for="app in sortedAndFilteredApps"
:key="app.name"
:app="app"
<!-- Favorite Apps Section -->
<div v-if="favoriteApps.length > 0" class="mb-10">
<h2 class="h2 text-2xl font-bold mb-4">Favorite Apps</h2> <!-- Applied h2 -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6"> <!-- Adjusted gap -->
<app-card
v-for="app in favoriteApps"
:key="app.appName"
:app="app"
@toggle-favorite="toggleFavorite"
@install="installApp"
@uninstall="uninstallApp"
@delete="deleteApp"
@edit="editApp"
@download="downloadApp"
@help="handleAppClick"
@open="openApp"
@start-server="startServer"
/>
</div>
</div>
<!-- All Apps Section (Filtered/Sorted) -->
<h2 class="h2 text-2xl font-bold mb-4">{{ currentCategoryName }} ({{ sortedAndFilteredApps.length }})</h2> <!-- Applied h2 -->
<div v-if="sortedAndFilteredApps.length > 0" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6"> <!-- Adjusted gap -->
<app-card
v-for="app in sortedAndFilteredApps"
:key="app.name"
:app="app"
@toggle-favorite="toggleFavorite"
@install="installApp"
@uninstall="uninstallApp"
@ -135,28 +154,33 @@
@start-server="startServer"
/>
</div>
<p v-else class="text-center text-blue-500 dark:text-blue-400 py-10">
No apps found in this category or matching your filters.
</p>
</div>
<!-- App details modal -->
<div v-if="selectedApp" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
<div class="bg-white rounded-lg p-6 w-11/12 h-5/6 flex flex-col">
<div class="flex justify-between items-center mb-4">
<h2 class="text-2xl font-bold">{{ selectedApp.name }}</h2>
<button @click="backToZoo" class="bg-gray-300 hover:bg-gray-400 px-4 py-2 rounded-lg transition duration-300 ease-in-out">Close</button>
<div v-if="selectedApp" class="fixed inset-0 bg-black bg-opacity-70 flex items-center justify-center z-50 p-4">
<!-- Applied card class -->
<div class="card w-11/12 max-w-4xl h-5/6 flex flex-col text-blue-900 dark:text-blue-100">
<div class="flex justify-between items-center mb-4 pb-2 border-b border-blue-300 dark:border-blue-600">
<h2 class="h3 !mb-0">{{ selectedApp.name }}</h2> <!-- Applied h3 -->
<button @click="backToZoo" class="btn btn-secondary btn-sm">Close</button> <!-- Applied btn, btn-secondary, btn-sm -->
</div>
<iframe v-if="appCode" :srcdoc="appCode" class="flex-grow border-none"></iframe>
<p v-else class="text-center text-red-500">Please install this app to view its code.</p>
<iframe v-if="appCode" :srcdoc="appCode" class="flex-grow border border-blue-200 dark:border-blue-700 rounded-md bg-white dark:bg-blue-900"></iframe> <!-- Styled iframe -->
<p v-else class="text-center text-red-600 dark:text-red-400 py-10">Please install this app to view its code.</p> <!-- Adjusted text color -->
</div>
</div>
<!-- Toast message -->
<div v-if="message" class="fixed bottom-4 right-4 px-6 py-3 rounded-lg shadow-md" :class="{ 'bg-green-100 text-green-800': successMessage, 'bg-red-100 text-red-800': !successMessage }">
<div v-if="message" class="fixed bottom-4 right-4 px-6 py-3 rounded-lg shadow-lg z-[100]" :class="{ 'bg-green-200 text-green-800 dark:bg-green-700 dark:text-green-100': successMessage, 'bg-red-200 text-red-800 dark:bg-red-800 dark:text-red-100': !successMessage }"> <!-- Adjusted toast colors and shadow -->
{{ message }}
</div>
</div>
</template>
<script>
import axios from 'axios';
import AppCard from '@/components/AppCard.vue'; // Create this component for individual app cards

View File

@ -1,15 +1,11 @@
<template>
<!-- Main container for the Personalities Zoo section -->
<div class="user-settings-panel flex flex-col mb-2 rounded-lg shadow-lg p-4">
<!-- Top Bar: Title, Active Personality, Mounted Personalities -->
<div class="flex flex-row justify-between items-center mb-4 flex-wrap gap-y-2">
<!-- Left Side: Title and Active Personality -->
<div class="flex items-center flex-wrap">
<p class="text-xl font-semibold cursor-default select-none mr-3 text-blue-800 dark:text-blue-100">
Personalities Zoo
</p>
<!-- Display Active Personality Name -->
<div v-if="active_personality_name" class="flex items-center mr-2 text-lg text-blue-600 dark:text-blue-300">
<span class="mx-2 text-blue-400 dark:text-blue-500">|</span>
<span class="font-bold line-clamp-1" :title="`Active: ${active_personality_name}`">
@ -18,26 +14,25 @@
</div>
</div>
<!-- Right Side: Mounted Personalities -->
<div class="flex items-center space-x-3 shrink-0">
<!-- Display Mounted Personalities Icons -->
<div v-if="mountedPersArr.length > 0" class="text-base font-semibold cursor-pointer select-none items-center flex flex-row">
<div v-if="mountedPersArr.length > 0" class="text-base font-semibold cursor-default select-none items-center flex flex-row">
<div class="flex -space-x-4 items-center">
<div class="relative hover:-translate-y-1 duration-300 hover:z-10 shrink-0"
v-for="(item, index) in displayedMountedPersonalities"
:key="index + '-' + item.name"
ref="mountedPersonalitiesRefs">
<div class="group items-center flex flex-row">
<div class="group/mounted items-center flex flex-row">
<button @click.stop="onPersonalitySelected({ personality: item, isMounted: true })"
:title="`Select: ${item.name}`">
:title="`Select: ${item.name}`"
class="transition-transform duration-150 ease-in-out active:scale-90">
<img :src="getPersonalityIconUrl(item.avatar)" @error="personalityImgPlaceholder"
class="w-8 h-8 rounded-full object-cover border-2 active:scale-90 group-hover:border-blue-500 dark:group-hover:border-blue-400"
class="w-8 h-8 rounded-full object-cover border-2 transition-colors duration-200 group-hover/mounted:border-blue-500 dark:group-hover/mounted:border-blue-400"
:class="isActivePersonality(item) ? 'border-blue-500 dark:border-blue-400' : 'border-blue-300 dark:border-blue-600'">
</button>
<button @click.stop="unmountPersonality({ personality: item })"
class="absolute -top-1 -right-1 opacity-0 group-hover:opacity-100 transition-opacity duration-150"
class="absolute -top-1 -right-1 opacity-0 group-hover/mounted:opacity-100 transition-all duration-150 ease-in-out hover:scale-110"
title="Unmount personality">
<span class="bg-red-500 hover:bg-red-600 text-white rounded-full p-0.5 flex items-center justify-center shadow-md">
<span class="bg-red-500 hover:bg-red-600 text-white rounded-full p-0.5 flex items-center justify-center shadow-md transition-colors duration-150">
<i data-feather="x" class="w-3 h-3 stroke-current"></i>
</span>
</button>
@ -51,52 +46,46 @@
</div>
</div>
<!-- Unmount All Button -->
<button v-if="mountedPersArr.length > 0" @click.stop="unmountAll()"
class="p-1 bg-red-100 hover:bg-red-200 dark:bg-red-900 dark:hover:bg-red-800 rounded-full border border-red-300 dark:border-red-700 active:scale-90"
class="p-1 bg-red-100 hover:bg-red-200 dark:bg-red-900 dark:hover:bg-red-800 rounded-full border border-red-300 dark:border-red-700 active:scale-90 transition-all duration-150"
title="Unmount All Personalities">
<i data-feather="x-octagon" class="w-4 h-4 text-red-600 dark:text-red-400 stroke-current"></i>
</button>
</div>
</div>
<!-- Filters and Search Area -->
<div class="flex flex-col sm:flex-row gap-4 mb-4">
<!-- SEARCH BAR -->
<div class="flex-grow">
<label for="personality-search" class="sr-only">Search</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
<i v-if="!searchPersonalityInProgress" data-feather="search" class="w-5 h-5 text-blue-400 dark:text-blue-500"></i>
<!-- SPINNER -->
<div v-else role="status">
<svg aria-hidden="true" class="w-5 h-5 text-blue-400 animate-spin dark:text-blue-500 fill-blue-500" viewBox="0 0 100 101" fill="none" xmlns="http://www.w3.org/2000/svg">
<svg aria-hidden="true" class="w-5 h-5 text-blue-400 animate-spin dark:text-blue-500 fill-blue-600 dark:fill-blue-300" viewBox="0 0 100 101" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z" fill="currentColor" />
<path d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z" fill="currentFill" />
</svg>
</div>
</div>
<input type="search" id="personality-search"
class="block w-full p-3 pl-10 text-sm input text-blue-900 dark:text-blue-100"
class="input search-input block w-full p-3 pl-10 text-sm text-blue-900 dark:text-blue-100 placeholder-blue-500 dark:placeholder-blue-400"
placeholder="Search name, author, description..." required v-model="searchPersonality"
@input="searchPersonality_func">
<button v-if="searchPersonality" @click.stop="clearSearch" type="button"
class="text-white absolute right-2.5 bottom-1.5 bg-blue-600 hover:bg-blue-700 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-xs px-3 py-1.5 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">
class="absolute right-2.5 bottom-1.5 btn btn-primary btn-sm text-xs px-3 py-1.5">
Clear
</button>
</div>
</div>
<!-- CATEGORY DROPDOWN -->
<div class="flex-shrink-0 sm:w-64">
<label for="persCat" class="sr-only">Category</label>
<select id="persCat"
v-model="selectedCategory"
@change="applyFiltersAndSort"
class="block w-full p-3 text-sm input text-blue-900 dark:text-blue-100">
class="input block w-full p-3 text-sm text-blue-900 dark:text-blue-100">
<option value="">All Categories ({{ allPersonalities.length }})</option>
<option v-if="starredPaths.length > 0" value="Starred"> Starred ({{ starredPaths.length }})</option>
<!-- Add a separator visually if needed -->
<option disabled v-if="starredPaths.length > 0 && persCatgArr.length > 0" class="text-blue-400 dark:text-blue-600"></option>
<option v-for="(item, index) in persCatgArr" :key="index" :value="item">
{{ item }} ({{ getCategoryCount(item) }})
@ -105,25 +94,21 @@
</div>
</div>
<!-- Loading State -->
<div v-if="isLoading && allPersonalities.length === 0" class="flex justify-center items-center p-10 text-blue-500 dark:text-blue-400">
<svg aria-hidden="true" class="w-8 h-8 mr-2 text-blue-300 animate-spin dark:text-blue-600 fill-blue-500" viewBox="0 0 100 101" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z" fill="currentColor"/> <path d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z" fill="currentFill"/> </svg>
<div v-if="isLoading && allPersonalities.length === 0" class="flex justify-center items-center p-10 text-loading">
<svg aria-hidden="true" class="w-8 h-8 mr-2 text-blue-400 animate-spin dark:text-blue-500 fill-blue-600 dark:fill-blue-300" viewBox="0 0 100 101" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z" fill="currentColor"/> <path d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z" fill="currentFill"/> </svg>
<span>Loading personalities...</span>
</div>
<!-- Empty State -->
<div v-else-if="fullyFilteredPersonalities.length === 0" class="text-center text-blue-500 dark:text-blue-400 py-10">
<div v-else-if="!isLoading && fullyFilteredPersonalities.length === 0" class="text-center text-blue-500 dark:text-blue-400 py-10">
No personalities found{{ searchPersonality ? ' matching "' + searchPersonality + '"' : '' }}{{ selectedCategory && selectedCategory !== 'Starred' ? ' in category "' + selectedCategory + '"' : '' }}{{ selectedCategory === 'Starred' ? ' in Starred' : '' }}.
</div>
<!-- PERSONALITIES GRID (Lazy Loaded) -->
<div v-else class="overflow-y-auto flex-grow personalities-grid-container scrollbar scrollbar-thin" style="max-height: calc(100vh - 300px);"> <!-- Added scrollbar styling -->
<label class="label block ml-2 mb-2"> <!-- Used label class -->
<div v-else class="overflow-y-auto flex-grow personalities-grid-container scrollbar" style="max-height: calc(100vh - 300px);">
<label class="label block ml-2 mb-2 text-blue-700 dark:text-blue-300">
{{ getResultLabel() }}: ({{ fullyFilteredPersonalities.length }})
</label>
<!-- Added key to the div for better conditional rendering updates -->
<div :key="selectedCategory + '-' + searchPersonality"
class="p-2 pb-0 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
class="p-2 pb-0 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4 bg-blue-100/50 dark:bg-blue-800/30 rounded-md">
<transition-group name="list">
<PersonalityEntry
v-for="(pers, index) in renderedPersonalities"
@ -151,10 +136,9 @@
/>
</transition-group>
</div>
<!-- Intersection Observer Sentinel -->
<div ref="sentinel" class="h-10">
<div v-if="isLoading && renderedPersonalities.length > 0 && renderedPersonalities.length < fullyFilteredPersonalities.length" class="flex justify-center items-center p-4 text-blue-500 dark:text-blue-400">
<svg aria-hidden="true" class="w-6 h-6 mr-2 text-blue-300 animate-spin dark:text-blue-600 fill-blue-500" viewBox="0 0 100 101" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z" fill="currentColor"/> <path d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z" fill="currentFill"/> </svg>
<div v-if="displayedCount < fullyFilteredPersonalities.length" class="flex justify-center items-center p-4 text-loading">
<svg aria-hidden="true" class="w-6 h-6 mr-2 text-blue-400 animate-spin dark:text-blue-500 fill-blue-600 dark:fill-blue-300" viewBox="0 0 100 101" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z" fill="currentColor"/> <path d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z" fill="currentFill"/> </svg>
<span>Loading more...</span>
</div>
</div>
@ -168,7 +152,6 @@ import feather from 'feather-icons';
import { nextTick } from 'vue';
import PersonalityEntry from "@/components/PersonalityEntry.vue";
import defaultPersonalityIcon from "@/assets/logo.png";
// Use mapState, mapActions, etc. if preferred, or access $store directly
const bUrl = import.meta.env.VITE_LOLLMS_API_BASEURL || '';
const STARRED_LOCAL_STORAGE_KEY = 'lollms_starred_personalities';
@ -178,30 +161,27 @@ export default {
components: {
PersonalityEntry,
},
emits: ['settings-changed'],
data() {
return {
allPersonalities: [],
persCatgArr: [],
selectedCategory: '', // Will be initialized based on store in mounted()
selectedCategory: '',
searchPersonality: '',
searchPersonalityInProgress: false,
searchDebounceTimer: null,
searchDebounceDelay: 350,
isLoading: false,
bUrl: bUrl, // Expose bUrl to the template if needed directly or for props
defaultPersonalityIcon_: defaultPersonalityIcon, // Expose for template usage
bUrl: bUrl,
defaultPersonalityIcon_: defaultPersonalityIcon,
maxDisplayedMounted: 5,
starredPaths: [], // Store full_path of starred personalities
starredPaths: [],
// Lazy Loading state
displayedCount: 24, // Initial number of items to display
loadBatchSize: 24, // Number of items to load each time
observer: null, // Intersection observer instance
displayedCount: 24,
loadBatchSize: 24,
observer: null,
};
},
computed: {
// Access store state
configFile() {
return this.$store.state.config || { personalities: [], active_personality_id: -1, personality_category: '' };
},
@ -223,7 +203,7 @@ export default {
return null;
}
const activePathWithOptionalLang = this.configFile.personalities[this.configFile.active_personality_id];
const activePath = activePathWithOptionalLang ? activePathWithOptionalLang.split(':')[0] : null; // Get path without language
const activePath = activePathWithOptionalLang ? activePathWithOptionalLang.split(':')[0] : null;
const activePers = this.allPersonalities.find(p => p.full_path === activePath);
return activePers ? activePers.name : null;
},
@ -232,21 +212,17 @@ export default {
return this.mountedPersArr.slice(0, this.maxDisplayedMounted);
},
// Core filtering logic (before slicing for lazy loading)
fullyFilteredPersonalities() {
let result = [...this.allPersonalities];
// Filter by Starred
if (this.selectedCategory === 'Starred') {
const starredSet = new Set(this.starredPaths);
result = result.filter(p => starredSet.has(p.full_path));
}
// Filter by Category (if not Starred)
else if (this.selectedCategory) {
result = result.filter(p => p.category === this.selectedCategory);
}
// Filter by Search Term
if (this.searchPersonality) {
const searchTerm = this.searchPersonality.toLowerCase();
result = result.filter((item) => {
@ -259,7 +235,6 @@ export default {
});
}
// Sort: Mounted first, then by name
result.sort((a, b) => {
if (a.isMounted && !b.isMounted) return -1;
if (!a.isMounted && b.isMounted) return 1;
@ -269,57 +244,45 @@ export default {
return result;
},
// Slice the filtered list for rendering based on lazy loading
renderedPersonalities() {
return this.fullyFilteredPersonalities.slice(0, this.displayedCount);
},
},
watch: {
// Watch store config for changes in mounted personalities
'configFile.personalities': {
handler() {
this.syncLocalMountedFlags();
},
deep: true // Necessary for arrays
deep: true
},
// Watch store config for category changes
'configFile.personality_category': {
handler(newVal) {
const currentVal = newVal || '';
// Only update local state if it differs AND is a valid category
if (this.selectedCategory !== currentVal && (this.persCatgArr.includes(currentVal) || currentVal === '' || currentVal === 'Starred')) {
this.selectedCategory = currentVal;
this.applyFiltersAndSort(); // Re-filter list
this.applyFiltersAndSort();
}
}
},
// Watch local selectedCategory to update store and potentially emit changes
selectedCategory(newVal) {
const storeVal = this.$store.state.config.personality_category || '';
if (storeVal !== newVal) {
this.$store.state.config.personality_category = newVal;
this.$emit('settings-changed');
}
// Filter/sort is handled by the @change event on the select element
// and the applyFiltersAndSort method. No need to call it here directly.
},
// Watch starred paths for changes
starredPaths: {
handler() {
// Refetch categories to potentially add/remove the "Starred" option
this.fetchCategories();
// Re-apply filters if the starred list changes and "Starred" is selected
// Only re-apply filters if the starred category is currently selected
if (this.selectedCategory === 'Starred') {
this.applyFiltersAndSort();
}
// Mark the `isStarred` flag on the main list
this.markStarredInAllPersonalities();
// No need to call markStarredInAllPersonalities here, toggleStar handles individual item
// No need to fetch categories unless counts *must* update instantly, which is rare
},
deep: true // Necessary for arrays
deep: true
}
},
methods: {
// --- API Helpers ---
async api_get_req(endpoint) {
try {
const res = await axios.get(`${endpoint.startsWith('/') ? '' : '/'}${endpoint}`);
@ -347,17 +310,17 @@ export default {
}
},
// --- Data Fetching & Processing ---
async getPersonalitiesArr() {
// Set loading true specifically for this async operation
this.isLoading = true;
try {
const dictionary = await this.api_get_req("get_all_personalities");
const config = this.configFile; // Use computed property
const config = this.configFile;
console.log("Processing get_all_personalities response");
let combined = [];
const mountedSet = new Set(config.personalities || []);
const starredSet = new Set(this.starredPaths); // Use current starred paths
const starredSet = new Set(this.starredPaths);
if (dictionary) {
for (const category in dictionary) {
@ -366,17 +329,16 @@ export default {
personalitiesInCategory.forEach((item) => {
const full_path = `${category}/${item.folder}`;
const uniqueId = item.id || full_path;
// Determine if *any* language variant is mounted
const langPaths = Array.isArray(item.languages) ? item.languages.map(lang => `${full_path}:${lang}`) : [];
const isAnyVariantMounted = mountedSet.has(full_path) || langPaths.some(lp => mountedSet.has(lp));
combined.push({
...item,
category: category,
language: "", // Base entry has no specific language set here
language: "",
full_path: full_path,
isMounted: isAnyVariantMounted,
isStarred: starredSet.has(full_path), // Set starred flag
isStarred: starredSet.has(full_path),
id: uniqueId,
isProcessing: false
});
@ -385,51 +347,63 @@ export default {
}
}
this.allPersonalities = combined;
this.applyFiltersAndSort(); // Apply initial filter/sort/slice
// Don't apply filters here yet, let mounted handle the first call after all data is ready
console.log(`Fetched ${this.allPersonalities.length} total personalities.`);
} finally {
this.isLoading = false; // Set loading false *after* processing
// Set loading false ONLY after this specific fetch and processing is done
this.isLoading = false;
nextTick(feather.replace);
}
},
async fetchCategories() {
this.isLoading = true; // Consider if separate loading state is needed here
// Avoid setting global isLoading here if called independently, let caller manage
try {
const cats = await this.api_get_req("list_personalities_categories");
this.persCatgArr = cats ? cats.sort() : [];
// Initialize selectedCategory based on store config *after* categories are fetched
const storedCat = this.configFile.personality_category;
const isValidStoredCat = storedCat && (this.persCatgArr.includes(storedCat) || storedCat === 'Starred');
this.selectedCategory = isValidStoredCat ? storedCat : ''; // Initialize here
// Initialize selectedCategory *after* categories are fetched if it wasn't set
if (!this.selectedCategory) {
this.selectedCategory = isValidStoredCat ? storedCat : '';
}
} finally {
this.isLoading = false;
nextTick(feather.replace); // Might need icon updates if categories change dynamically
// Avoid setting global isLoading here
nextTick(feather.replace);
}
},
async fetchPersonalitiesAndCategories() {
await this.fetchCategories(); // Fetch categories first
await this.getPersonalitiesArr(); // Then fetch personalities
// Manage loading state around the combined operation
this.isLoading = true;
try {
this.loadStarred(); // Load starred status first
await this.fetchCategories();
await this.getPersonalitiesArr();
// Now that all data is potentially loaded, apply initial filters/sort
this.applyFiltersAndSort();
} catch (error) {
console.error("Error fetching personalities and categories:", error);
// Handle error appropriately, maybe show a toast
} finally {
this.isLoading = false; // Global loading false after everything
nextTick(() => {
feather.replace();
this.setupObserver(); // Setup observer after initial render and data
});
}
},
// --- Filtering, Sorting, Searching ---
applyFiltersAndSort() {
// Reset displayed count when filters change
this.displayedCount = this.loadBatchSize;
this.searchPersonalityInProgress = false; // Ensure spinner stops
// Computed properties `fullyFilteredPersonalities` and `renderedPersonalities`
// will automatically update based on `selectedCategory`, `searchPersonality`,
// `allPersonalities`, and `displayedCount`.
this.searchPersonalityInProgress = false;
nextTick(() => {
feather.replace();
// Reset scroll position to top when filters change
const gridContainer = this.$el.querySelector('.personalities-grid-container'); // Use $el
const gridContainer = this.$el?.querySelector('.personalities-grid-container');
if (gridContainer) {
gridContainer.scrollTop = 0;
}
// Re-observe after potential list changes
// Re-observe might be needed if the list drastically changes
this.setupObserver();
});
},
@ -445,7 +419,6 @@ export default {
this.applyFiltersAndSort();
},
// --- Starred Functionality ---
loadStarred() {
try {
const stored = localStorage.getItem(STARRED_LOCAL_STORAGE_KEY);
@ -454,7 +427,7 @@ export default {
console.error("Failed to load starred personalities:", e);
this.starredPaths = [];
}
this.markStarredInAllPersonalities(); // Mark initially
// No need to call markStarredInAllPersonalities here, getPersonalitiesArr handles initial marking
},
saveStarred() {
try {
@ -463,39 +436,48 @@ export default {
console.error("Failed to save starred personalities:", e);
}
},
// This function is likely redundant now if getPersonalitiesArr sets initial state
// and toggleStar updates individual items. Keeping it just in case, but likely removable.
markStarredInAllPersonalities() {
const starredSet = new Set(this.starredPaths);
this.allPersonalities.forEach(p => {
p.isStarred = starredSet.has(p.full_path);
});
// Force update if needed, although changing array item properties should be reactive
// this.allPersonalities = [...this.allPersonalities];
// Filtering/sorting will happen naturally when applyFiltersAndSort is called
},
toggleStar(persEntry) {
const path = persEntry.personality.full_path;
const index = this.starredPaths.indexOf(path);
let newStarredState;
if (index > -1) {
this.starredPaths.splice(index, 1); // Unstar
newStarredState = false;
} else {
this.starredPaths.push(path); // Star
newStarredState = true;
}
// Find the personality in the *master* list and update its flag directly
// Update the flag directly on the personality object in the master list
const masterPers = this.allPersonalities.find(p => p.full_path === path);
if (masterPers) {
masterPers.isStarred = index === -1; // True if it was just added
masterPers.isStarred = newStarredState;
} else {
console.warn("Could not find personality in master list to update starred state:", path);
}
this.saveStarred(); // Persist change
// Small toast notification
this.$store.state.toast.showToast(
`${persEntry.personality.name} ${index > -1 ? 'unstarred' : 'starred'}`,
this.saveStarred();
this.$store.state.toast.showToast(
`${persEntry.personality.name} ${newStarredState ? 'starred' : 'unstarred'}`,
2, true
);
nextTick(feather.replace);
// Vue's reactivity should update the PersonalityEntry via the computed prop `fullyFilteredPersonalities`
// and the `:is-starred` binding. No explicit re-render needed usually.
// The watcher on starredPaths handles potential list re-filtering if needed.
nextTick(feather.replace); // Still replace icons just in case
},
// --- UI & State Helpers ---
syncLocalMountedFlags() {
const mountedSet = new Set(this.configFile.personalities || []);
let changed = false;
@ -510,7 +492,8 @@ export default {
}
});
if(changed){
this.applyFiltersAndSort(); // Re-filter/sort if mounted status changed
// Apply filters again if mounted status changed, as it affects sorting
this.applyFiltersAndSort();
}
nextTick(feather.replace);
},
@ -519,9 +502,8 @@ export default {
if (!avatarPath) return this.defaultPersonalityIcon_;
const path = avatarPath.startsWith('/') ? avatarPath : `/${avatarPath}`;
const separator = this.bUrl.endsWith('/') || path.startsWith('/') ? '' : '/';
let finalPath = path.startsWith('/') ? path.substring(1) : path; // Remove leading slash if present
finalPath = finalPath === '/' ? '' : finalPath; // Handle root path case
// Construct the final URL using the exposed bUrl data property
let finalPath = path.startsWith('/') ? path.substring(1) : path;
finalPath = finalPath === '/' ? '' : finalPath;
return `${this.bUrl}${separator}${finalPath}`;
},
isActivePersonality(pers) {
@ -536,9 +518,8 @@ export default {
const pers = list.find(p => (p.id || p.full_path) === id);
if (pers) pers.isProcessing = state;
};
findAndUpdate(this.allPersonalities); // Update master list
// Vue's reactivity should handle updates in computed props automatically
nextTick(feather.replace); // Update icons if needed
findAndUpdate(this.allPersonalities);
nextTick(feather.replace);
},
getCategoryCount(category) {
return this.allPersonalities.filter(p => p.category === category).length;
@ -550,7 +531,6 @@ export default {
return 'All Personalities';
},
// --- Action Handlers ---
async onPersonalitySelected(persEntry) {
const pers = persEntry.personality;
if (this.isLoading) { this.$store.state.toast.showToast("Loading...", 4, false); return; }
@ -563,7 +543,6 @@ export default {
const res = await this.select_personality(pers);
if (res && res.status) {
this.$emit('settings-changed');
this.$store.state.toast.showToast(`Selected personality: ${pers.name}`, 4, true);
} else {
this.$store.state.toast.showToast(`Failed to select ${pers.name}: ${res?.error || 'Unknown error'}`, 4, false);
@ -574,7 +553,6 @@ export default {
async select_personality(pers) {
if (!pers) { return { 'status': false, 'error': 'no personality - select_personality' } }
let pth = pers.language ? `${pers.full_path}:${pers.language}` : pers.full_path;
// Find index in the *current* store config personalities array
const id = this.$store.state.config.personalities.findIndex(item => item === pth || item === pers.full_path);
if (id === -1) {
@ -583,7 +561,7 @@ export default {
console.error("Personality path not found in store config:", pth, pers.full_path);
return { 'status': false, 'error': 'Personality path not found in current config' };
}
pth = pers.full_path; // Use base path if found
pth = pers.full_path;
}
const finalId = this.$store.state.config.personalities.findIndex(item => item === pth);
@ -596,7 +574,7 @@ export default {
try {
const res = await axios.post(`/select_personality`, obj, {headers: { 'Content-Type': 'application/json' }});
if (res && res.data) {
await this.$store.dispatch('refreshConfig'); // Refresh store config
await this.$store.dispatch('refreshConfig');
return res.data;
} else {
return { status: false, error: 'No response data from select_personality' };
@ -620,15 +598,12 @@ export default {
const res = await this.mount_personality(pers);
if (res && res.status && res.active_personality_id > -1 && res.personalities) {
// Directly update store state (or dispatch an action)
this.$store.state.config.personalities = res.personalities;
this.$store.state.config.active_personality_id = res.active_personality_id;
this.$emit('settings-changed');
this.$store.state.toast.showToast("Personality mounted and selected", 4, true);
// syncLocalMountedFlags will be called by the watcher on configFile.personalities
} else {
this.$store.state.toast.showToast(`Could not mount personality\nError: ${res?.error || 'Unknown error'}`, 4, false);
this.syncLocalMountedFlags(); // Resync on error too
this.syncLocalMountedFlags();
}
this.setPersonalityProcessing(persEntry, false);
nextTick(feather.replace);
@ -661,15 +636,12 @@ export default {
const res = await this.unmount_personality(pers);
if (res && res.status) {
// Directly update store state (or dispatch an action)
this.$store.state.config.personalities = res.personalities;
this.$store.state.config.active_personality_id = res.active_personality_id;
this.$emit('settings-changed');
this.$store.state.toast.showToast("Personality unmounted", 4, true);
// syncLocalMountedFlags will be called by the watcher on configFile.personalities
} else {
this.$store.state.toast.showToast(`Could not unmount personality\nError: ${res?.error || 'Unknown error'}`, 4, false);
this.syncLocalMountedFlags(); // Resync on error
this.syncLocalMountedFlags();
}
this.setPersonalityProcessing(persEntry, false);
nextTick(feather.replace);
@ -695,16 +667,14 @@ export default {
if (!yes) return;
this.$store.state.toast.showToast(`Unmounting all...`, 3, true);
this.isLoading = true; // Use global loading state
this.isLoading = true;
const res = await this.api_post_req('/unmount_all_personalities');
if (res && res.status) {
this.$store.state.config.personalities = [];
this.$store.state.config.active_personality_id = -1;
this.$emit('settings-changed');
this.$store.state.toast.showToast(`All personalities unmounted.`, 4, true);
// syncLocalMountedFlags will be called by the watcher
} else {
this.$store.state.toast.showToast(`Failed to unmount all: ${res?.error || 'Unknown error'}`, 4, false);
}
@ -717,24 +687,20 @@ export default {
this.$store.state.toast.showToast(`Remounting ${pers.name}...`, 3, true);
try {
await this.unmount_personality(pers);
await new Promise(resolve => setTimeout(resolve, 150)); // Small delay
await new Promise(resolve => setTimeout(resolve, 150));
const res = await this.mount_personality(pers);
if (res && res.status) {
this.$store.state.config.personalities = res.personalities;
this.$store.state.config.active_personality_id = res.active_personality_id;
this.$emit('settings-changed');
this.$store.state.toast.showToast(`${pers.name} remounted successfully.`, 4, true);
// Watcher will trigger syncLocalMountedFlags
} else {
this.$store.state.toast.showToast(`Failed to remount ${pers.name}: ${res?.error || 'Mount failed'}`, 4, false);
await this.fetchPersonalitiesAndCategories(); // Fetch again to resync state fully
// syncLocalMountedFlags called implicitly
await this.fetchPersonalitiesAndCategories();
}
} catch (error) {
this.$store.state.toast.showToast(`Error remounting ${pers.name}: ${error.message}`, 4, false);
await this.fetchPersonalitiesAndCategories();
// syncLocalMountedFlags called implicitly
} finally {
this.setPersonalityProcessing(persEntry, false);
}
@ -746,7 +712,7 @@ export default {
const res = await axios.post(`/get_personality_config`, {
client_id: this.$store.state.client_id,
category: pers.category,
name: pers.folder, // Use folder name here
name: pers.folder,
});
const data = res.data;
if (data.status) {
@ -775,7 +741,7 @@ export default {
this.setPersonalityProcessing(persEntry, true);
const res = await this.api_post_req('copy_to_custom_personas', {
category: pers.category,
name: pers.folder // Assuming original intent was folder name
name: pers.folder
});
if (res && res.status) {
@ -783,8 +749,7 @@ export default {
`"${pers.name}" copied to 'custom_personalities'. Refreshing list...`
);
await new Promise(resolve => setTimeout(resolve, 500));
await this.fetchPersonalitiesAndCategories(); // Refetch everything
// syncLocalMountedFlags called implicitly
await this.fetchPersonalitiesAndCategories();
} else {
this.$store.state.toast.showToast(`Failed to copy ${pers.name}: ${res?.error || 'Already exists?'}`, 4, false);
}
@ -801,7 +766,6 @@ export default {
if (res && res.status) {
this.$store.state.toast.showToast(`${pers.name} reinstalled successfully.`, 4, true);
// Maybe refetch or remount if needed
} else {
this.$store.state.toast.showToast(`Failed to reinstall ${pers.name}: ${res?.error || 'Not found?'}`, 4, false);
}
@ -854,35 +818,31 @@ export default {
await this.api_post_req("open_personality_folder", { category: pers.category, name: pers.folder });
},
// --- Lazy Loading ---
loadMore() {
if (this.isLoading) return; // Don't load more if already loading something else
if (this.displayedCount >= this.fullyFilteredPersonalities.length) return; // All loaded
if (this.isLoading) return;
if (this.displayedCount >= this.fullyFilteredPersonalities.length) return;
console.log("Loading more personalities...");
this.displayedCount += this.loadBatchSize;
nextTick(feather.replace); // Update icons for newly added items
nextTick(feather.replace);
},
setupObserver() {
// Disconnect previous observer if exists
if (this.observer) {
this.observer.disconnect();
}
// Use this.$refs which is available after mount
const sentinel = this.$refs.sentinel;
if (!sentinel) {
//console.warn("Sentinel element not found for Intersection Observer.");
return; // Exit if sentinel isn't rendered yet
return;
}
const options = {
root: null, // Use the viewport
root: null,
rootMargin: '0px',
threshold: 0.1 // Trigger when 10% of the sentinel is visible
threshold: 0.1
};
this.observer = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting) {
if (entries[0].isIntersecting && !this.isLoading) { // Check isLoading to prevent parallel loading
this.loadMore();
}
}, options);
@ -890,36 +850,24 @@ export default {
this.observer.observe(sentinel);
},
},
// --- Lifecycle Hooks ---
async mounted() {
console.log("PersonalitiesZoo mounted (Options API). Initializing...");
this.isLoading = true; // Set loading true at the start
this.loadStarred(); // Load starred before fetching
await this.fetchPersonalitiesAndCategories(); // Fetch data
// Initial category sync from store happens within fetchCategories now
nextTick(() => {
feather.replace();
this.setupObserver(); // Setup observer after initial render and data fetch
});
this.isLoading = false; // Set loading false after initialization
console.log("PersonalitiesZoo mounted. Initializing...");
// Initial data fetch is handled by fetchPersonalitiesAndCategories
await this.fetchPersonalitiesAndCategories();
// Initial sync and observer setup happens within fetchPersonalitiesAndCategories finally block
console.log("PersonalitiesZoo initialization complete.");
},
beforeUnmount() {
// Clean up observer
if (this.observer) {
this.observer.disconnect();
this.observer = null;
}
// Clear debounce timer
clearTimeout(this.searchDebounceTimer);
},
updated() {
// This can be useful for ensuring Feather icons are replaced after any reactive update
// However, calling it within specific methods using nextTick is often more targeted.
nextTick(() => {
feather.replace();
});
},
}
</script>
</script>