Initial WallMuse project

This commit is contained in:
fenglee
2026-05-09 09:12:41 +00:00
commit 3ea7d29827
91 changed files with 13136 additions and 0 deletions

801
apps/web/src/app/globals.css Executable file
View File

@@ -0,0 +1,801 @@
* {
box-sizing: border-box;
}
html {
min-height: 100%;
background: var(--color-bg-page);
}
body {
min-height: 100vh;
margin: 0;
color: var(--color-text-primary);
background:
linear-gradient(135deg, rgba(255, 255, 255, 0.72), transparent 34%),
linear-gradient(145deg, var(--color-bg-page), #d9ecff 45%, var(--color-bg-page));
font-size: var(--font-md);
font-family: Inter, "PingFang SC", "Microsoft YaHei", system-ui, sans-serif;
letter-spacing: 0;
}
[data-theme="dark"] body {
background:
linear-gradient(140deg, rgba(102, 170, 255, 0.12), transparent 38%),
linear-gradient(145deg, var(--color-bg-page), #0c1b30 58%, #07111f);
}
a {
color: inherit;
text-decoration: none;
}
button,
input,
textarea,
select {
font: inherit;
}
button {
cursor: pointer;
}
img {
display: block;
max-width: 100%;
}
:focus-visible {
outline: 2px solid var(--color-accent);
outline-offset: 3px;
}
.page-stage {
min-height: 100vh;
padding: 24px;
}
.app-shell {
width: min(1800px, 100%);
min-height: calc(100vh - 48px);
margin: 0 auto;
overflow: hidden;
border: 1px solid var(--color-border-soft);
border-radius: var(--radius-xl);
background: var(--color-bg-surface);
box-shadow: var(--shadow-shell);
backdrop-filter: var(--glass-blur);
}
.top-nav {
display: grid;
grid-template-columns: auto minmax(280px, 660px) auto;
gap: 24px;
align-items: center;
min-height: 88px;
padding: 18px 34px;
border-bottom: 1px solid var(--color-border-soft);
background: var(--color-bg-surface-strong);
backdrop-filter: var(--glass-blur);
}
.brand {
display: inline-flex;
align-items: center;
gap: 12px;
min-width: 0;
font-size: var(--font-xl);
font-weight: 750;
}
.brand-mark {
display: grid;
grid-template-columns: repeat(4, 5px);
gap: 3px;
align-items: end;
width: 40px;
height: 40px;
padding: 9px;
border: 1px solid var(--color-border-strong);
border-radius: 15px;
background: linear-gradient(145deg, rgba(255, 255, 255, 0.68), rgba(47, 134, 255, 0.14));
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.7);
}
[data-theme="dark"] .brand-mark {
background: linear-gradient(145deg, rgba(102, 170, 255, 0.2), rgba(8, 18, 32, 0.72));
}
.brand-mark span {
border-radius: var(--radius-full);
background: linear-gradient(180deg, #9ed3ff, var(--color-accent));
}
.brand-mark span:nth-child(1) {
height: 14px;
}
.brand-mark span:nth-child(2) {
height: 22px;
}
.brand-mark span:nth-child(3) {
height: 18px;
}
.brand-mark span:nth-child(4) {
height: 26px;
}
.search-box {
display: flex;
align-items: center;
gap: 12px;
height: 52px;
min-width: 0;
padding: 0 16px;
border: 1px solid var(--color-border-soft);
border-radius: var(--radius-lg);
background: var(--color-bg-control);
color: var(--color-text-secondary);
}
.search-box input {
min-width: 0;
width: 100%;
border: 0;
outline: 0;
background: transparent;
color: var(--color-text-primary);
}
.search-box kbd {
flex: 0 0 auto;
border: 1px solid var(--color-border-soft);
border-radius: var(--radius-xs);
padding: 3px 7px;
color: var(--color-text-muted);
font-size: var(--font-xs);
}
.nav-actions {
display: flex;
align-items: center;
justify-content: flex-end;
gap: 10px;
}
.icon-button,
.glass-button {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 8px;
min-height: 44px;
border: 1px solid var(--color-border-soft);
background: var(--color-bg-control);
color: var(--color-text-primary);
transition: transform 180ms ease, border-color 180ms ease, box-shadow 180ms ease;
backdrop-filter: var(--glass-blur);
}
.icon-button {
width: 44px;
border-radius: var(--radius-full);
}
.glass-button {
padding: 0 16px;
border-radius: var(--radius-full);
font-weight: 650;
}
.icon-button:hover,
.glass-button:hover {
transform: translateY(-1px);
border-color: var(--color-border-strong);
box-shadow: var(--shadow-card);
}
.primary-button {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 10px;
min-height: 48px;
border: 0;
border-radius: var(--radius-full);
padding: 0 20px;
background: linear-gradient(135deg, #2f86ff, #66aaff);
color: #fff;
font-weight: 760;
box-shadow: 0 14px 30px rgba(47, 134, 255, 0.28);
}
.avatar {
display: grid;
place-items: center;
width: 44px;
height: 44px;
border: 1px solid var(--color-border-strong);
border-radius: var(--radius-full);
background: var(--color-accent-soft);
color: var(--color-accent);
font-weight: 800;
}
.shell-content {
padding: 30px 34px 36px;
}
.page-grid {
display: grid;
gap: 24px;
}
.hero-strip {
display: grid;
grid-template-columns: minmax(0, 1.1fr) minmax(340px, 0.9fr);
gap: 24px;
align-items: stretch;
}
.glass-panel {
border: 1px solid var(--color-border-soft);
border-radius: var(--radius-xl);
background: var(--color-bg-surface);
box-shadow: var(--shadow-card);
backdrop-filter: var(--glass-blur);
}
.hero-composer {
min-height: 326px;
padding: 28px;
}
.eyebrow {
display: inline-flex;
align-items: center;
gap: 8px;
margin: 0 0 16px;
color: var(--color-accent);
font-size: var(--font-sm);
font-weight: 750;
}
.hero-composer h1,
.page-title h1 {
margin: 0;
max-width: 780px;
font-size: var(--font-3xl);
line-height: 1.08;
letter-spacing: 0;
}
.hero-composer p,
.page-title p {
margin: 14px 0 0;
max-width: 720px;
color: var(--color-text-secondary);
line-height: 1.7;
}
.prompt-bar {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
gap: 12px;
margin-top: 26px;
}
.prompt-bar textarea,
.field textarea,
.field input,
.field select {
width: 100%;
border: 1px solid var(--color-border-soft);
border-radius: var(--radius-md);
background: var(--color-bg-surface-strong);
color: var(--color-text-primary);
outline: 0;
}
.prompt-bar textarea {
min-height: 96px;
resize: vertical;
padding: 15px 16px;
}
.quick-specs {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-top: 18px;
}
.pill {
display: inline-flex;
align-items: center;
gap: 7px;
min-height: 34px;
padding: 0 12px;
border: 1px solid var(--color-border-soft);
border-radius: var(--radius-full);
background: var(--color-bg-control);
color: var(--color-text-secondary);
font-size: var(--font-sm);
font-weight: 650;
}
.feature-preview {
position: relative;
min-height: 326px;
overflow: hidden;
}
.feature-preview img {
width: 100%;
height: 100%;
min-height: 326px;
object-fit: cover;
}
.preview-metadata {
position: absolute;
right: 18px;
bottom: 18px;
left: 18px;
display: flex;
justify-content: space-between;
gap: 12px;
padding: 14px;
border: 1px solid rgba(255, 255, 255, 0.26);
border-radius: var(--radius-md);
background: rgba(4, 10, 18, 0.48);
color: #fff;
backdrop-filter: blur(18px);
}
.category-rail {
display: flex;
gap: 10px;
overflow-x: auto;
padding: 2px 0 8px;
scrollbar-width: thin;
}
.category-pill {
flex: 0 0 auto;
min-height: 42px;
border: 1px solid var(--color-border-soft);
border-radius: var(--radius-full);
padding: 0 16px;
background: var(--color-bg-control);
color: var(--color-text-secondary);
font-weight: 650;
}
.category-pill.active {
border-color: var(--color-border-strong);
background: var(--color-bg-control-active);
color: var(--color-accent);
}
.wallpaper-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
gap: 22px;
}
.wallpaper-card {
position: relative;
isolation: isolate;
overflow: hidden;
min-height: 260px;
border: 1px solid transparent;
border-radius: var(--radius-md);
background: var(--color-bg-control);
box-shadow: var(--shadow-card);
transition: transform 180ms ease, border-color 180ms ease, box-shadow 180ms ease;
}
.wallpaper-card:hover,
.wallpaper-card:focus-within {
transform: translateY(-2px);
border-color: var(--color-border-strong);
box-shadow: var(--shadow-floating);
}
.wallpaper-card img {
width: 100%;
height: 100%;
min-height: 260px;
object-fit: cover;
transition: transform 180ms ease;
}
.wallpaper-card:hover img {
transform: scale(1.02);
}
.wallpaper-card.portrait {
grid-row: span 2;
}
.wallpaper-card.portrait img,
.wallpaper-card.portrait {
min-height: 520px;
}
.card-badge,
.card-more,
.card-stats,
.card-actions {
position: absolute;
z-index: 2;
}
.card-badge {
top: 12px;
left: 12px;
padding: 7px 10px;
border: 1px solid rgba(255, 255, 255, 0.28);
border-radius: var(--radius-full);
background: rgba(255, 255, 255, 0.58);
color: #172235;
font-size: var(--font-xs);
font-weight: 850;
backdrop-filter: blur(14px);
}
.card-more {
top: 10px;
right: 10px;
}
.card-stats {
right: 12px;
bottom: 12px;
left: 12px;
display: flex;
justify-content: space-between;
gap: 10px;
padding: 10px 12px;
border: 1px solid rgba(255, 255, 255, 0.16);
border-radius: var(--radius-sm);
background: rgba(4, 10, 18, 0.52);
color: #fff;
font-size: var(--font-sm);
backdrop-filter: blur(16px);
}
.card-actions {
top: 50%;
left: 50%;
display: flex;
gap: 10px;
opacity: 0;
transform: translate(-50%, -44%);
transition: opacity 180ms ease, transform 180ms ease;
}
.wallpaper-card:hover .card-actions,
.wallpaper-card:focus-within .card-actions {
opacity: 1;
transform: translate(-50%, -50%);
}
.floating-action {
width: 48px;
height: 48px;
border: 1px solid rgba(255, 255, 255, 0.24);
border-radius: var(--radius-full);
background: rgba(255, 255, 255, 0.28);
color: #fff;
backdrop-filter: blur(18px);
}
.section-heading {
display: flex;
align-items: flex-end;
justify-content: space-between;
gap: 16px;
margin-bottom: 16px;
}
.section-heading h2 {
margin: 0;
font-size: var(--font-xl);
}
.section-heading p {
margin: 5px 0 0;
color: var(--color-text-secondary);
}
.form-layout {
display: grid;
grid-template-columns: minmax(320px, 420px) minmax(0, 1fr) minmax(280px, 340px);
gap: 22px;
align-items: start;
}
.panel-pad {
padding: 22px;
}
.field {
display: grid;
gap: 8px;
margin-bottom: 16px;
}
.field label {
color: var(--color-text-secondary);
font-size: var(--font-sm);
font-weight: 700;
}
.field textarea {
min-height: 132px;
resize: vertical;
padding: 13px 14px;
}
.field input,
.field select {
height: 46px;
padding: 0 13px;
}
.segmented {
display: grid;
grid-auto-flow: column;
grid-auto-columns: 1fr;
gap: 6px;
padding: 5px;
border: 1px solid var(--color-border-soft);
border-radius: var(--radius-md);
background: var(--color-bg-control);
}
.segmented button {
min-height: 38px;
border: 0;
border-radius: var(--radius-sm);
background: transparent;
color: var(--color-text-secondary);
font-weight: 700;
}
.segmented button.active {
background: var(--color-bg-control-active);
color: var(--color-accent);
}
.switch-row {
display: flex;
align-items: center;
justify-content: space-between;
gap: 14px;
min-height: 48px;
margin-bottom: 12px;
padding: 10px 12px;
border: 1px solid var(--color-border-soft);
border-radius: var(--radius-md);
background: var(--color-bg-control);
}
.switch-row input {
width: 18px;
height: 18px;
}
.result-pair {
display: grid;
grid-template-columns: minmax(0, 1.6fr) minmax(180px, 0.75fr);
gap: 18px;
align-items: start;
}
.result-frame {
overflow: hidden;
border: 1px solid var(--color-border-soft);
border-radius: var(--radius-md);
background: var(--color-bg-control);
}
.result-frame.landscape {
aspect-ratio: 16 / 9;
}
.result-frame.portrait {
aspect-ratio: 9 / 16;
}
.result-frame img {
width: 100%;
height: 100%;
object-fit: cover;
}
.task-list {
display: grid;
gap: 12px;
}
.task-item {
display: grid;
gap: 8px;
padding: 13px;
border: 1px solid var(--color-border-soft);
border-radius: var(--radius-md);
background: var(--color-bg-control);
}
.status-line {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
color: var(--color-text-secondary);
font-size: var(--font-sm);
}
.score {
display: inline-flex;
align-items: center;
gap: 7px;
color: var(--color-success);
font-weight: 800;
}
.auth-layout {
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(320px, 420px);
gap: 24px;
align-items: stretch;
}
.auth-art {
position: relative;
overflow: hidden;
min-height: 560px;
}
.auth-art img {
width: 100%;
height: 100%;
min-height: 560px;
object-fit: cover;
}
.settings-layout {
display: grid;
grid-template-columns: minmax(320px, 460px) minmax(0, 1fr);
gap: 22px;
}
.key-row {
display: grid;
gap: 12px;
padding: 16px;
border: 1px solid var(--color-border-soft);
border-radius: var(--radius-md);
background: var(--color-bg-control);
}
.footer-note {
margin-top: 24px;
color: var(--color-text-muted);
font-size: var(--font-sm);
}
@media (min-width: 1600px) {
.wallpaper-grid {
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 26px;
}
}
@media (max-width: 1199px) {
.hero-strip,
.form-layout,
.auth-layout,
.settings-layout {
grid-template-columns: 1fr;
}
.form-layout {
align-items: stretch;
}
}
@media (max-width: 899px) {
.page-stage {
padding: 0;
}
.app-shell {
min-height: 100vh;
border-width: 0;
border-radius: 0;
}
.top-nav {
grid-template-columns: 1fr auto;
gap: 14px;
min-height: 64px;
padding: 12px 16px;
}
.top-nav .search-box {
grid-column: 1 / -1;
height: 48px;
}
.shell-content {
padding: 18px 16px 28px;
}
.nav-actions .glass-button span,
.search-box kbd {
display: none;
}
.hero-composer {
padding: 20px;
}
.hero-composer h1,
.page-title h1 {
font-size: var(--font-2xl);
}
.prompt-bar {
grid-template-columns: 1fr;
}
.wallpaper-grid {
grid-template-columns: 1fr;
gap: 16px;
}
.wallpaper-card.portrait,
.wallpaper-card.portrait img {
min-height: 440px;
}
.result-pair {
grid-template-columns: 1fr;
}
}
@media (max-width: 479px) {
.brand {
font-size: var(--font-lg);
}
.brand-mark {
width: 36px;
height: 36px;
padding: 8px;
}
.hero-composer h1,
.page-title h1 {
font-size: 25px;
}
.preview-metadata,
.section-heading,
.status-line {
align-items: flex-start;
flex-direction: column;
}
.auth-art,
.auth-art img {
min-height: 360px;
}
}