Add public profiles and cosmetic shop
All checks were successful
Deploy MineGeo to Dokploy / deploy (push) Successful in 7m10s

This commit is contained in:
2026-10-15 17:30:10 +05:00
parent 44e62cff2f
commit c541cc09b4
28 changed files with 1359 additions and 45 deletions

409
app/profile-cosmetics.css Normal file
View File

@@ -0,0 +1,409 @@
.profile-avatar-shell {
display: inline-grid;
position: relative;
isolation: isolate;
place-items: center;
flex: none;
line-height: 0;
vertical-align: middle;
}
.profile-avatar-shell > .player-avatar {
position: relative;
z-index: 1;
}
.profile-avatar-shell[data-effect]::before,
.profile-avatar-shell[data-effect]::after {
content: "";
position: absolute;
pointer-events: none;
}
.profile-avatar-shell[data-effect="redstone-pulse"]::before {
inset: -4px;
border: 2px solid #ef6556;
border-radius: 8px;
box-shadow: 0 0 8px #ef655688, inset 0 0 6px #ef655655;
animation: redstone-pulse 1.8s ease-in-out infinite;
}
.profile-avatar-shell[data-effect="ender-orbit"]::before {
inset: -5px;
border: 1px solid #ad83fa;
border-radius: 50%;
box-shadow: 0 0 9px #8d62e877;
transform: rotate(-24deg) scaleX(0.74);
animation: ender-orbit 3.4s linear infinite;
}
.profile-avatar-shell[data-effect="ender-orbit"]::after {
width: 5px;
height: 5px;
top: -4px;
right: 0;
border-radius: 50%;
background: #d3b7ff;
box-shadow: 0 0 8px #a780ff;
}
.profile-avatar-shell[data-effect="nether-flame"]::before {
inset: -6px;
border: 2px solid #ff8c43;
border-radius: 7px;
box-shadow: 0 0 9px #f4632d99, inset 0 -5px 10px #f4632d55;
animation: nether-flicker 1.2s ease-in-out infinite alternate;
}
.profile-avatar-shell[data-effect="nether-flame"]::after {
inset: -8px -3px;
border-radius: 50%;
border-top: 1px solid #ffd27c;
border-bottom: 1px solid #f4632d99;
filter: blur(1px);
opacity: 0.7;
animation: nether-flicker 1.7s ease-in-out infinite alternate-reverse;
}
.profile-avatar-shell[data-effect="aurora-crown"]::before {
inset: -6px;
border-radius: 50%;
background: conic-gradient(
from 0deg,
#72f3d4,
#75a9ff,
#c89bff,
#72f3d4
);
-webkit-mask: radial-gradient(
farthest-side,
transparent calc(100% - 2px),
#000 calc(100% - 1px)
);
mask: radial-gradient(
farthest-side,
transparent calc(100% - 2px),
#000 calc(100% - 1px)
);
filter: drop-shadow(0 0 5px #78e7d5aa);
animation: aurora-turn 5s linear infinite;
}
.profile-name-link {
color: inherit;
text-decoration: none;
}
.dashboard-profile-actions {
margin: 20px 0 34px;
}
.profile-name-link:hover,
.profile-name-link:focus-visible {
color: var(--green);
text-decoration: underline;
text-underline-offset: 3px;
}
.public-profile-page {
max-width: 900px;
}
.public-profile-hero {
display: flex;
align-items: center;
gap: 28px;
margin: 34px 0 28px;
padding: 32px;
border: 1px solid var(--line);
background:
radial-gradient(ellipse at 12% 50%, #84c8a31b, transparent 55%),
var(--panel);
box-shadow: 4px 4px #03070b;
}
.public-profile-avatar {
width: 88px;
height: 88px;
box-shadow: 4px 4px #03070b;
}
.public-profile-copy h1 {
margin: 8px 0;
overflow-wrap: anywhere;
}
.public-profile-copy p {
margin: 0;
font-size: 13px;
}
.public-profile-about {
margin: 28px 0;
padding: 24px 28px;
border: 1px solid var(--line);
background: var(--panel);
}
.public-profile-about h2 {
margin-bottom: 12px;
font-size: 23px;
}
.public-profile-bio {
margin: 0;
color: var(--muted);
line-height: 1.8;
white-space: pre-line;
overflow-wrap: anywhere;
}
.public-profile-stats {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 16px;
}
.public-profile-stat {
display: grid;
grid-template-columns: auto 1fr;
align-items: center;
gap: 8px 12px;
padding: 18px;
border: 1px solid var(--line);
background: var(--panel);
}
.public-profile-stat > svg {
color: var(--green);
}
.public-profile-stat > span {
color: var(--muted);
font-size: 12px;
}
.public-profile-stat > strong {
grid-column: 2;
font-size: 25px;
}
.public-profile-footnote {
margin: 16px 0;
color: var(--muted);
font-size: 11px;
}
.cosmetics-shop {
margin-top: 30px;
}
.cosmetics-shop-heading {
display: flex;
align-items: end;
justify-content: space-between;
gap: 30px;
margin-bottom: 24px;
}
.cosmetics-shop-heading h1 {
margin: 10px 0;
font-size: clamp(38px, 6vw, 60px);
line-height: 1;
}
.cosmetics-shop-heading .lead {
max-width: 610px;
margin: 0;
}
.cosmetics-wallet {
display: flex;
align-items: center;
gap: 13px;
flex: none;
min-width: 190px;
padding: 16px 19px;
border: 1px solid #d8bd72;
background: #241f14;
box-shadow: 3px 3px #03070b;
color: #f0d891;
}
.cosmetics-wallet > span {
display: grid;
gap: 5px;
}
.cosmetics-wallet small {
color: #bcae84;
font-size: 9px;
letter-spacing: 0.12em;
}
.cosmetics-wallet strong {
font-size: 16px;
}
.cosmetics-earning-note {
display: flex;
align-items: center;
gap: 10px;
margin: 18px 0 28px;
padding: 13px 16px;
border: 1px solid var(--line);
background: var(--panel);
color: var(--muted);
font-size: 12px;
}
.cosmetics-earning-note svg {
flex: none;
color: #d8bd72;
}
.cosmetics-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
gap: 18px;
}
.cosmetic-card {
display: flex;
flex-direction: column;
min-width: 0;
min-height: 350px;
padding: 18px;
border: 1px solid var(--line);
border-top: 3px solid #7b8c83;
background: var(--panel);
box-shadow: 3px 3px #03070b;
}
.cosmetic-card[data-rarity="rare"] {
border-top-color: #8984d8;
}
.cosmetic-card[data-rarity="epic"] {
border-top-color: #e08b55;
}
.cosmetic-card[data-rarity="legendary"] {
border-top-color: #79d4bd;
}
.cosmetic-card-top {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
min-height: 20px;
}
.cosmetic-rarity {
color: var(--muted);
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.1em;
}
.cosmetic-equipped {
display: inline-flex;
align-items: center;
gap: 4px;
color: var(--green);
font-size: 10px;
}
.cosmetic-preview {
display: grid;
place-items: center;
min-height: 128px;
margin: 12px 0 14px;
border: 1px solid var(--line);
background:
radial-gradient(circle, #9caa7122 0, transparent 58%),
#0b1117;
}
.cosmetic-preview-avatar {
width: 64px;
height: 64px;
box-shadow: 3px 3px #03070b;
}
.cosmetic-card h2 {
margin: 0 0 8px;
font-size: 21px;
}
.cosmetic-card > p {
flex: 1;
margin: 0 0 18px;
color: var(--muted);
font-size: 12px;
line-height: 1.7;
}
.cosmetic-card-action .button {
width: 100%;
min-height: 42px;
}
.cosmetics-real-money-note {
margin: 24px 0 0;
color: var(--muted);
font-size: 11px;
}
@keyframes redstone-pulse {
0%, 100% { opacity: 0.65; box-shadow: 0 0 5px #ef655655; }
50% { opacity: 1; box-shadow: 0 0 13px #ef6556bb, inset 0 0 6px #ef655655; }
}
@keyframes ender-orbit {
to { transform: rotate(336deg) scaleX(0.74); }
}
@keyframes nether-flicker {
from { opacity: 0.58; filter: saturate(0.9); }
to { opacity: 1; filter: saturate(1.25); }
}
@keyframes aurora-turn {
to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
.profile-avatar-shell[data-effect]::before,
.profile-avatar-shell[data-effect]::after {
animation: none;
}
}
@media (max-width: 680px) {
.public-profile-hero {
gap: 20px;
padding: 22px;
}
.cosmetics-shop-heading {
align-items: stretch;
flex-direction: column;
}
.cosmetics-wallet {
width: max-content;
}
}
@media (max-width: 480px) {
.public-profile-hero {
align-items: flex-start;
flex-direction: column;
}
.public-profile-stats {
grid-template-columns: 1fr;
}
}