Adapt + improve all public pages to the atom design system
Extended the same design-system treatment to the public site, faithful to AtomCMS's "atom" theme. New src/components/public/ui.tsx provides the signature atom building blocks + a scoped CSS layer: - ContentCard: surface card with a primary-tinted header (icon circle + title + subtitle) and padded body — the atom content-card, used as every page's header and section wrapper. - StatBlock / stat-grid, EmptyState, OnlineBadge (online/offline pill), RankBadge (medals for the top 3), and responsive .card-grid helpers. Swept ~45 public pages (home/community/rankings hand-built as the reference; the rest via parallel agents that read the schema and preserved every query, server action, auth gate and field name): heroes → ContentCard headers, lists → card-grids in ContentCards, "no X" → EmptyState, status → OnlineBadge/RankBadge. The leaderboard gained Credits/Diamonds/Duckets tabs (usersCurrency). Behaviour unchanged. Verified on the prod server against amx_test: 15+ public pages render the content-cards/grids with real data, no errors; computed styles confirm the tinted header, icon circle, medal + online pills. Fixed an undefined --color-golden ref. tsc 0, vitest 49/49, next build 0.
This commit is contained in:
1 parent
0de0ac6a3c
commit
e9ea19795a
47 files changed
+2264
-1714
No files matched your search
@@ -679,3 +679,164 @@ td {
|
||||
margin: 0 0 0.7rem;
|
||||
font-size: 1.15rem;
|
||||
}
|
||||
|
||||
/* ── Public design system (faithful to the atom theme) ──────────
|
||||
content-card = surface card with a primary-tinted header (icon +
|
||||
title + subtitle) and a padded body — the signature atom block. */
|
||||
.content-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
background: var(--color-surface);
|
||||
color: var(--color-text);
|
||||
border: 1px solid color-mix(in srgb, var(--color-text-muted) 15%, transparent);
|
||||
border-radius: 14px;
|
||||
box-shadow: var(--shadow-card);
|
||||
overflow: hidden;
|
||||
}
|
||||
.content-card-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.7rem;
|
||||
padding: 0.85rem 1rem;
|
||||
background: color-mix(in srgb, var(--color-primary) 9%, var(--color-surface));
|
||||
border-bottom: 1px solid color-mix(in srgb, var(--color-text-muted) 10%, transparent);
|
||||
}
|
||||
.content-card-icon {
|
||||
flex: none;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 999px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
font-size: 1.25rem;
|
||||
background: color-mix(in srgb, var(--color-primary) 18%, var(--color-surface));
|
||||
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--color-primary) 30%, transparent);
|
||||
}
|
||||
.content-card-head-text {
|
||||
min-width: 0;
|
||||
flex: 1;
|
||||
}
|
||||
.content-card-title {
|
||||
margin: 0;
|
||||
font-weight: 700;
|
||||
font-size: 1rem;
|
||||
line-height: 1.2;
|
||||
}
|
||||
.content-card-subtitle {
|
||||
margin: 0.15rem 0 0;
|
||||
font-size: 0.78rem;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
.content-card-action {
|
||||
flex: none;
|
||||
}
|
||||
.content-card-body {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
/* Responsive card grids (atom: 1 / sm2 / md3 / lg4). */
|
||||
.card-grid {
|
||||
display: grid;
|
||||
gap: 1rem;
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
@media (min-width: 40rem) {
|
||||
.card-grid.sm-2 { grid-template-columns: repeat(2, 1fr); }
|
||||
}
|
||||
@media (min-width: 48rem) {
|
||||
.card-grid.md-2 { grid-template-columns: repeat(2, 1fr); }
|
||||
.card-grid.md-3 { grid-template-columns: repeat(3, 1fr); }
|
||||
}
|
||||
@media (min-width: 64rem) {
|
||||
.card-grid.lg-3 { grid-template-columns: repeat(3, 1fr); }
|
||||
.card-grid.lg-4 { grid-template-columns: repeat(4, 1fr); }
|
||||
}
|
||||
|
||||
/* Stat tiles (value in the primary colour + muted label). */
|
||||
.stat-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
|
||||
gap: 0.85rem;
|
||||
}
|
||||
.stat-block {
|
||||
background: var(--color-background);
|
||||
border: 1px solid color-mix(in srgb, var(--color-text-muted) 12%, transparent);
|
||||
border-radius: 12px;
|
||||
padding: 0.85rem 1rem;
|
||||
text-align: center;
|
||||
}
|
||||
.stat-block-value {
|
||||
font-size: 1.6rem;
|
||||
font-weight: 800;
|
||||
line-height: 1.1;
|
||||
color: var(--color-primary);
|
||||
}
|
||||
.stat-block-label {
|
||||
margin-top: 0.2rem;
|
||||
font-size: 0.78rem;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
/* Empty states */
|
||||
.empty-state {
|
||||
text-align: center;
|
||||
padding: 2rem 1rem;
|
||||
}
|
||||
.empty-state-icon {
|
||||
font-size: 2rem;
|
||||
margin-bottom: 0.4rem;
|
||||
}
|
||||
|
||||
/* Online / offline pill */
|
||||
.online-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.35rem;
|
||||
font-size: 0.74rem;
|
||||
font-weight: 700;
|
||||
padding: 0.1rem 0.55rem 0.1rem 0.45rem;
|
||||
border-radius: 999px;
|
||||
background: color-mix(in srgb, var(--color-text-muted) 14%, transparent);
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
.online-badge.online {
|
||||
background: color-mix(in srgb, #16a34a 16%, transparent);
|
||||
color: #15803d;
|
||||
}
|
||||
.online-dot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 999px;
|
||||
background: currentColor;
|
||||
}
|
||||
.online-badge.online .online-dot {
|
||||
background: #16a34a;
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, #16a34a 22%, transparent);
|
||||
}
|
||||
|
||||
/* Leaderboard rank chip */
|
||||
.rank-badge {
|
||||
display: inline-grid;
|
||||
place-items: center;
|
||||
min-width: 2.1rem;
|
||||
height: 2.1rem;
|
||||
padding: 0 0.35rem;
|
||||
border-radius: 999px;
|
||||
font-weight: 800;
|
||||
font-size: 0.95rem;
|
||||
background: var(--color-background);
|
||||
border: 1px solid color-mix(in srgb, var(--color-text-muted) 18%, transparent);
|
||||
}
|
||||
.rank-badge.rank-1 {
|
||||
background: color-mix(in srgb, #eab308 20%, transparent);
|
||||
border-color: #eab308;
|
||||
}
|
||||
.rank-badge.rank-2 {
|
||||
background: color-mix(in srgb, #94a3b8 22%, transparent);
|
||||
border-color: #94a3b8;
|
||||
}
|
||||
.rank-badge.rank-3 {
|
||||
background: color-mix(in srgb, #f97316 20%, transparent);
|
||||
border-color: #f97316;
|
||||
}
|
||||
Reference in new issue
Block a user