349 lines
9.3 KiB
CSS
349 lines
9.3 KiB
CSS
@import "tailwindcss";
|
||
|
||
/* ─────────────────────────────────────────
|
||
Design tokens → Tailwind theme
|
||
───────────────────────────────────────── */
|
||
@theme {
|
||
--color-accent: #b49acb;
|
||
--color-accent2: #91a8d0;
|
||
--color-apptext: #2c2b2d;
|
||
--color-muted: #6c6870;
|
||
--color-bg1: #f8f5f2;
|
||
--color-bg2: #e9f0f7;
|
||
--color-bg3: #f4eaf1;
|
||
|
||
--font-serif: 'KaiTi', 'STKaiti', '楷体', '楷体_GB2312', serif;
|
||
|
||
--shadow-card: 0 20px 50px rgba(33, 33, 40, 0.12);
|
||
--radius-default: 8px;
|
||
|
||
/* glass helpers as raw values (used in @layer) */
|
||
--glass-bg: rgba(255, 255, 255, 0.55);
|
||
--glass-strong-bg: rgba(255, 255, 255, 0.72);
|
||
--line-color: rgba(255, 255, 255, 0.35);
|
||
}
|
||
|
||
/* ─────────────────────────────────────────
|
||
Base layer
|
||
───────────────────────────────────────── */
|
||
@layer base {
|
||
*, *::before, *::after { box-sizing: border-box; }
|
||
|
||
html {
|
||
scrollbar-width: none;
|
||
background-color: var(--color-bg1);
|
||
}
|
||
html::-webkit-scrollbar { display: none; }
|
||
|
||
body {
|
||
margin: 0;
|
||
min-height: 100vh;
|
||
font-family: var(--font-serif);
|
||
font-size: 18px;
|
||
color: var(--color-apptext);
|
||
background: transparent;
|
||
}
|
||
|
||
h1, h2, h3, h4 {
|
||
font-family: var(--font-serif);
|
||
margin: 0;
|
||
}
|
||
|
||
p { margin: 0; }
|
||
|
||
button {
|
||
font-family: var(--font-serif);
|
||
cursor: pointer;
|
||
}
|
||
}
|
||
|
||
/* ─────────────────────────────────────────
|
||
Shared component classes
|
||
───────────────────────────────────────── */
|
||
@layer components {
|
||
|
||
/* Glass surfaces */
|
||
.glass {
|
||
background: var(--glass-bg);
|
||
border: 1px solid var(--line-color);
|
||
backdrop-filter: blur(16px);
|
||
-webkit-backdrop-filter: blur(16px);
|
||
}
|
||
|
||
.glass-strong {
|
||
background: var(--glass-strong-bg);
|
||
border: 1px solid var(--line-color);
|
||
backdrop-filter: blur(20px);
|
||
-webkit-backdrop-filter: blur(20px);
|
||
}
|
||
|
||
/* Card wrapper used on every page */
|
||
.page-card {
|
||
background: var(--glass-bg);
|
||
border: 1px solid var(--line-color);
|
||
border-radius: var(--radius-default);
|
||
padding: 26px;
|
||
box-shadow: var(--shadow-card);
|
||
backdrop-filter: blur(16px);
|
||
-webkit-backdrop-filter: blur(16px);
|
||
}
|
||
|
||
/* Button variants */
|
||
.ghost {
|
||
background: rgba(255, 255, 255, 0.6);
|
||
color: var(--color-apptext);
|
||
border: 1px solid var(--line-color);
|
||
font-size: 17px;
|
||
font-weight: 700;
|
||
font-family: var(--font-serif);
|
||
padding: 10px 18px;
|
||
border-radius: 8px;
|
||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||
}
|
||
.ghost:hover { transform: translateY(-1px); }
|
||
|
||
.primary {
|
||
background: linear-gradient(135deg, var(--color-accent), var(--color-accent2));
|
||
color: #fff;
|
||
font-family: var(--font-serif);
|
||
padding: 10px 18px;
|
||
border-radius: 8px;
|
||
border: none;
|
||
box-shadow: 0 10px 30px rgba(145, 168, 208, 0.35);
|
||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||
}
|
||
.primary:hover { transform: translateY(-1px); }
|
||
|
||
/* Badge */
|
||
.badge {
|
||
padding: 4px 10px;
|
||
border-radius: 6px;
|
||
font-size: 14px;
|
||
background: rgba(255, 255, 255, 0.7);
|
||
}
|
||
|
||
/* Form fields */
|
||
.form-field {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 6px;
|
||
margin-bottom: 12px;
|
||
}
|
||
|
||
.form-field input,
|
||
.form-field textarea {
|
||
border-radius: 8px;
|
||
border: 1px solid var(--line-color);
|
||
background: rgba(255, 255, 255, 0.7);
|
||
padding: 10px 12px;
|
||
font-family: var(--font-serif);
|
||
font-size: 18px;
|
||
color: var(--color-apptext);
|
||
outline: none;
|
||
}
|
||
.form-field textarea {
|
||
min-height: 120px;
|
||
resize: vertical;
|
||
}
|
||
|
||
/* Markdown rendered content (can't use Tailwind for inner HTML) */
|
||
.markdown {
|
||
font-size: 15px;
|
||
color: var(--color-muted);
|
||
line-height: 1.6;
|
||
display: -webkit-box;
|
||
-webkit-box-orient: vertical;
|
||
-webkit-line-clamp: 3;
|
||
overflow: hidden;
|
||
}
|
||
.markdown p { margin: 0 0 0.5em; }
|
||
.markdown ul { padding-left: 1.2em; }
|
||
.markdown a { color: var(--color-accent2); }
|
||
.markdown strong { font-weight: 700; color: var(--color-apptext); }
|
||
|
||
/* Product grid */
|
||
.product-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(5, minmax(0, 1fr));
|
||
gap: 20px;
|
||
align-items: stretch;
|
||
}
|
||
|
||
/* Shared tag text */
|
||
.tag {
|
||
font-size: 14px;
|
||
color: var(--color-muted);
|
||
}
|
||
|
||
/* Admin two-column layout (used globally in admin) */
|
||
.admin-grid {
|
||
display: grid;
|
||
grid-template-columns: 320px 1fr;
|
||
gap: 24px;
|
||
}
|
||
|
||
/* Detail two-column layout */
|
||
.detail-layout {
|
||
display: grid;
|
||
grid-template-columns: 1.1fr 1fr;
|
||
gap: 24px;
|
||
}
|
||
|
||
/* Table */
|
||
.table {
|
||
width: 100%;
|
||
border-collapse: collapse;
|
||
}
|
||
.table th,
|
||
.table td {
|
||
text-align: left;
|
||
padding: 12px;
|
||
font-size: 16px;
|
||
}
|
||
.table tr {
|
||
border-bottom: 1px solid var(--line-color);
|
||
}
|
||
|
||
/* Random background layer (full-page) */
|
||
.app-randbg {
|
||
position: fixed;
|
||
inset: 0;
|
||
z-index: -1;
|
||
overflow: hidden;
|
||
pointer-events: none;
|
||
background: radial-gradient(circle at top, var(--color-bg2), transparent 60%),
|
||
radial-gradient(circle at 10% 20%, var(--color-bg3), transparent 55%),
|
||
linear-gradient(140deg, var(--color-bg1), #fefefe 65%);
|
||
}
|
||
.app-randbg-img {
|
||
position: absolute;
|
||
left: 50%;
|
||
top: 50%;
|
||
min-width: calc(100% + 48px);
|
||
min-height: calc(100% + 48px);
|
||
width: auto;
|
||
height: auto;
|
||
transform: translate(-50%, -50%) scale(1.06);
|
||
object-fit: cover;
|
||
filter: blur(10px);
|
||
-webkit-filter: blur(10px);
|
||
}
|
||
|
||
/* Buy button */
|
||
.buy-button {
|
||
background: linear-gradient(135deg, var(--color-accent), var(--color-accent2));
|
||
color: #fff;
|
||
padding: 12px 22px;
|
||
border-radius: 8px;
|
||
font-family: var(--font-serif);
|
||
font-size: 17px;
|
||
border: none;
|
||
cursor: pointer;
|
||
transition: transform 0.2s ease;
|
||
}
|
||
.buy-button:hover { transform: translateY(-1px); }
|
||
|
||
/* Secondary link */
|
||
.secondary-link {
|
||
display: inline-flex;
|
||
justify-content: center;
|
||
padding: 8px 14px;
|
||
border-radius: 6px;
|
||
border: 1px solid rgba(255, 255, 255, 0.6);
|
||
background: rgba(255, 255, 255, 0.6);
|
||
color: var(--color-apptext);
|
||
font-size: 15px;
|
||
text-decoration: none;
|
||
transition: background 0.2s ease;
|
||
}
|
||
.secondary-link:hover { background: rgba(255, 255, 255, 0.85); }
|
||
}
|
||
|
||
/* ─────────────────────────────────────────
|
||
Vue <Transition> classes – cannot be in @layer components
|
||
because the names are generated at runtime by Vue
|
||
───────────────────────────────────────── */
|
||
|
||
/* Admin modal */
|
||
.modal-enter-active,
|
||
.modal-leave-active {
|
||
transition: opacity 0.25s ease;
|
||
}
|
||
.modal-enter-active .admin-modal,
|
||
.modal-leave-active .admin-modal {
|
||
transition: transform 0.25s ease, opacity 0.25s ease;
|
||
}
|
||
.modal-enter-from,
|
||
.modal-leave-to { opacity: 0; }
|
||
.modal-enter-from .admin-modal {
|
||
transform: scale(0.92) translateY(10px);
|
||
opacity: 0;
|
||
}
|
||
.modal-leave-to .admin-modal {
|
||
transform: scale(0.95);
|
||
opacity: 0;
|
||
}
|
||
|
||
/* PWA update toast */
|
||
.pwa-toast-enter-active,
|
||
.pwa-toast-leave-active {
|
||
transition: opacity 0.3s, transform 0.3s;
|
||
}
|
||
.pwa-toast-enter-from,
|
||
.pwa-toast-leave-to {
|
||
opacity: 0;
|
||
transform: translateX(-50%) translateY(16px);
|
||
}
|
||
|
||
/* Splash fade */
|
||
.splash-fade-leave-active {
|
||
transition: opacity 0.45s ease, transform 0.45s ease;
|
||
}
|
||
.splash-fade-leave-to {
|
||
opacity: 0;
|
||
transform: scale(1.04);
|
||
}
|
||
|
||
/* Chat panel slide */
|
||
.chat-slide-enter-active,
|
||
.chat-slide-leave-active {
|
||
transition: opacity 0.22s ease, transform 0.22s ease;
|
||
}
|
||
.chat-slide-enter-from,
|
||
.chat-slide-leave-to {
|
||
opacity: 0;
|
||
transform: translateY(20px) scale(0.96);
|
||
}
|
||
|
||
/* Chat icon flip */
|
||
.icon-flip-enter-active,
|
||
.icon-flip-leave-active {
|
||
transition: opacity 0.15s, transform 0.15s;
|
||
}
|
||
.icon-flip-enter-from,
|
||
.icon-flip-leave-to {
|
||
opacity: 0;
|
||
transform: rotate(90deg) scale(0.7);
|
||
}
|
||
|
||
/* ─────────────────────────────────────────
|
||
Responsive overrides (global)
|
||
───────────────────────────────────────── */
|
||
@media (max-width: 900px) {
|
||
.product-grid {
|
||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||
gap: 10px;
|
||
}
|
||
.admin-grid { grid-template-columns: 1fr; }
|
||
.detail-layout { grid-template-columns: 1fr; }
|
||
|
||
.page-card { padding: 14px; }
|
||
|
||
.btn-ghost.ghost {
|
||
font-size: 12px;
|
||
font-weight: 700;
|
||
padding: 5px 7px;
|
||
white-space: nowrap;
|
||
}
|
||
}
|