Files
MeBox/web/src/index.css
T
2026-09-18 11:28:33 +08:00

469 lines
18 KiB
CSS
Vendored

@tailwind base;
@tailwind components;
@tailwind utilities;
/* ── 自托管 Web 字体(OFL 许可,latin 子集,public/fonts/)──
取代原先 fonts.googleapis.com 的渲染阻塞外链:自托管服务常部署在
无法访问 Google 的网络,外链会拖住首屏渲染直到超时。 */
@font-face {
font-family: 'Geist';
font-style: normal;
font-weight: 300;
font-display: swap;
src: url('/fonts/geist-300.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
font-family: 'Geist';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('/fonts/geist-400.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
font-family: 'Geist';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url('/fonts/geist-500.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
font-family: 'Geist';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url('/fonts/geist-600.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
font-family: 'Geist';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url('/fonts/geist-700.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
font-family: 'JetBrains Mono';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('/fonts/jetbrainsmono-400.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
font-family: 'JetBrains Mono';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url('/fonts/jetbrainsmono-500.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
font-family: 'JetBrains Mono';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url('/fonts/jetbrainsmono-600.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
html, body, #root { height: 100%; }
:root {
--app-bg: #f9fafb;
--app-panel: #ffffff;
--app-panel-soft: #f9fafb;
--app-header-bg: rgba(255, 255, 255, 0.82);
--app-control-bg: rgba(249, 250, 251, 0.72);
--app-hover: #f3f4f6;
--app-active-bg: #111827;
--app-active-text: #ffffff;
--app-active-icon: #c9954a;
--app-command-bg: #111827;
--app-command-text: #ffffff;
--app-tooltip-bg: #111827;
--app-tooltip-text: #ffffff;
--app-brand-soft: rgba(255, 248, 231, 0.9);
--app-brand-text: #9a6a1e;
--app-brand-border: rgba(234, 214, 182, 0.9);
--app-brand-emphasis: rgba(201, 149, 74, 0.18);
--app-danger-soft: rgba(254, 242, 242, 0.9);
--app-text: #111827;
--app-subtle: #374151;
--app-muted: #6b7280;
--app-border: rgba(229, 231, 235, 0.82);
--app-shadow: rgba(17, 24, 39, 0.08);
--app-hero-bg: radial-gradient(circle at 80% 20%, rgba(212, 175, 55, 0.22), transparent 34%), linear-gradient(135deg, #fff7ed, #f8fafc 52%, #eef2ff);
--app-hero-overlay: linear-gradient(90deg, #ffffff 0%, rgba(255,255,255,0.96) 37%, rgba(255,255,255,0.62) 68%, rgba(255,255,255,0.2) 100%);
--app-hero-fade: linear-gradient(to top, #ffffff, transparent);
--app-poster-shell: #ffffff;
--app-poster-empty: linear-gradient(135deg, #f9fafb, #fff7ed);
}
:root[data-theme='dark'] {
--app-bg: #070a0f;
--app-panel: #0f141d;
--app-panel-soft: #111827;
--app-header-bg: rgba(15, 20, 29, 0.86);
--app-control-bg: rgba(17, 24, 39, 0.72);
--app-hover: #1f2937;
--app-active-bg: #1f2937;
--app-active-text: #f9fafb;
--app-active-icon: #e3b56d;
--app-command-bg: #f9fafb;
--app-command-text: #0b1018;
--app-tooltip-bg: #f9fafb;
--app-tooltip-text: #0b1018;
--app-brand-soft: rgba(201, 149, 74, 0.14);
--app-brand-text: #e3b56d;
--app-brand-border: rgba(201, 149, 74, 0.34);
--app-brand-emphasis: rgba(201, 149, 74, 0.18);
--app-danger-soft: rgba(127, 29, 29, 0.22);
--app-text: #f9fafb;
--app-subtle: #d1d5db;
--app-muted: #9ca3af;
--app-border: rgba(55, 65, 81, 0.82);
--app-shadow: rgba(0, 0, 0, 0.45);
--app-hero-bg: radial-gradient(circle at 78% 18%, rgba(201, 149, 74, 0.18), transparent 34%), linear-gradient(135deg, #0b1018, #101826 54%, #171f2d);
--app-hero-overlay: linear-gradient(90deg, rgba(7,10,15,0.98) 0%, rgba(15,20,29,0.92) 42%, rgba(15,20,29,0.62) 70%, rgba(15,20,29,0.24) 100%);
--app-hero-fade: linear-gradient(to top, #0f141d, transparent);
--app-poster-shell: #141b26;
--app-poster-empty: linear-gradient(135deg, #111827, #1f2937);
}
body {
background-color: var(--app-bg);
color: var(--app-text);
margin: 0;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* ─── Selection ─── */
::selection {
background: rgba(201, 149, 74, 0.2);
color: var(--app-text);
}
/* ─── Focus Ring ─── */
*:focus-visible {
outline: 2px solid #c9954a;
outline-offset: 2px;
border-radius: 6px;
}
/* ─── Scrollbar ─── */
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: #e5e7eb; border-radius: 999px; }
::-webkit-scrollbar-thumb:hover { background: #c9954a; }
:root[data-theme='dark'] ::-webkit-scrollbar-thumb { background: #374151; }
:root[data-theme='dark'] .bg-white,
:root[data-theme='dark'] .bg-gray-50,
:root[data-theme='dark'] .bg-gray-50\/50,
:root[data-theme='dark'] .bg-gray-50\/60,
:root[data-theme='dark'] .bg-gray-50\/70,
:root[data-theme='dark'] .bg-gray-50\/80,
:root[data-theme='dark'] .bg-gray-50\/90,
:root[data-theme='dark'] .bg-white\/50,
:root[data-theme='dark'] .bg-white\/60,
:root[data-theme='dark'] .bg-white\/70,
:root[data-theme='dark'] .bg-white\/75,
:root[data-theme='dark'] .bg-white\/80,
:root[data-theme='dark'] .bg-white\/82,
:root[data-theme='dark'] .bg-white\/85,
:root[data-theme='dark'] .bg-white\/90,
:root[data-theme='dark'] .bg-white\/95 {
background-color: var(--app-panel) !important;
}
:root[data-theme='dark'] .bg-gray-100,
:root[data-theme='dark'] .bg-gray-100\/50,
:root[data-theme='dark'] .bg-gray-100\/60,
:root[data-theme='dark'] .bg-gray-100\/70,
:root[data-theme='dark'] .bg-gray-100\/80 {
background-color: var(--app-hover) !important;
}
:root[data-theme='dark'] .bg-brand-50,
:root[data-theme='dark'] .bg-primary-400\/10,
:root[data-theme='dark'] .bg-primary-400\/15,
:root[data-theme='dark'] .bg-primary-400\/20,
:root[data-theme='dark'] .bg-sand-50,
:root[data-theme='dark'] .bg-amber-50,
:root[data-theme='dark'] .bg-yellow-50,
:root[data-theme='dark'] .bg-emerald-50,
:root[data-theme='dark'] .bg-green-50,
:root[data-theme='dark'] .bg-red-50 {
background-color: var(--app-control-bg) !important;
}
:root[data-theme='dark'] .bg-\[\#f9fafb\] {
background-color: var(--app-bg) !important;
}
:root[data-theme='dark'] .hover\:bg-gray-50:hover,
:root[data-theme='dark'] .hover\:bg-gray-50\/50:hover,
:root[data-theme='dark'] .hover\:bg-gray-100:hover,
:root[data-theme='dark'] .hover\:bg-brand-50:hover,
:root[data-theme='dark'] .hover\:bg-primary-400\/10:hover,
:root[data-theme='dark'] .hover\:bg-red-100:hover {
background-color: var(--app-hover) !important;
}
:root[data-theme='dark'] .text-gray-900,
:root[data-theme='dark'] .text-gray-950,
:root[data-theme='dark'] .text-\[\#111827\],
:root[data-theme='dark'] .text-ink-600,
:root[data-theme='dark'] .text-ink-500,
:root[data-theme='dark'] .text-ink-400,
:root[data-theme='dark'] .text-ink-300,
:root[data-theme='dark'] .text-ink-200,
:root[data-theme='dark'] .text-ink-100 {
color: var(--app-text) !important;
}
:root[data-theme='dark'] .text-gray-700,
:root[data-theme='dark'] .text-gray-600,
:root[data-theme='dark'] .text-gray-500,
:root[data-theme='dark'] .text-ink-50,
:root[data-theme='dark'] .text-sand-500 {
color: var(--app-muted) !important;
}
:root[data-theme='dark'] .border-gray-100,
:root[data-theme='dark'] .border-gray-200,
:root[data-theme='dark'] .border-gray-200\/50,
:root[data-theme='dark'] .border-gray-200\/60,
:root[data-theme='dark'] .border-gray-200\/80,
:root[data-theme='dark'] .border-gray-200\/90,
:root[data-theme='dark'] .border-gray-300 {
border-color: var(--app-border) !important;
}
:root[data-theme='dark'] .shadow-xl,
:root[data-theme='dark'] .shadow-2xl,
:root[data-theme='dark'] .shadow-md,
:root[data-theme='dark'] .shadow-sm {
box-shadow: 0 18px 50px var(--app-shadow) !important;
}
:root[data-theme='dark'] input,
:root[data-theme='dark'] select,
:root[data-theme='dark'] textarea {
color: var(--app-text) !important;
background-color: var(--app-panel-soft) !important;
border-color: var(--app-border) !important;
}
:root[data-theme='dark'] input::placeholder,
:root[data-theme='dark'] textarea::placeholder {
color: #6b7280;
}
.scrollbar-hide {
-ms-overflow-style: none;
scrollbar-width: none;
}
.scrollbar-hide::-webkit-scrollbar { display: none; }
/* ── 播放器底部动作面板的高度上限 ──
手机上按视口高度算(86%),老浏览器不认识 dvh 时退回 vh,避免面板
在 flex 容器里被内容撑出屏幕。 */
.player-sheet-height {
max-height: 86vh;
max-height: 86dvh;
}
/* ─── Reduced Motion ─── */
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
@layer components {
.theme-hero-bg { background: var(--app-hero-bg); }
.theme-hero-overlay { background: var(--app-hero-overlay); }
.theme-hero-fade { background: var(--app-hero-fade); }
/* ── Unified Swiss-Editorial Cards ── */
.card {
@apply rounded-2xl bg-white border border-gray-200/80 shadow-[0_1px_3px_rgba(0,0,0,0.01),0_1px_2px_rgba(0,0,0,0.015)] p-4 sm:p-6;
}
.card-hover {
@apply card transition-all duration-300 ease-out hover:border-gray-300 hover:shadow-[0_12px_32px_rgba(17,24,39,0.04),0_4px_12px_rgba(17,24,39,0.01)] hover:-translate-y-1;
}
.card-elevated {
@apply card shadow-[0_20px_40px_rgba(17,24,39,0.05),0_1px_3px_rgba(17,24,39,0.01)];
}
/* ── Glassmorphic Bright Panels ── */
.glass-panel {
@apply rounded-2xl bg-white border border-gray-200 shadow-sm p-4 sm:p-6;
}
.glass-card {
@apply rounded-2xl bg-white border border-gray-200 shadow-sm p-4 sm:p-6;
}
.glass-card-elevated {
@apply rounded-2xl bg-white border border-gray-200 shadow-md p-4 sm:p-6;
}
/* ── Input Fields Redesign ── */
.input-field {
@apply w-full rounded-xl border border-gray-200 bg-gray-50/50 px-4 py-3 text-sm text-gray-900
placeholder:text-gray-400 outline-none transition-all duration-300 ease-out
focus:border-brand-500 focus:bg-white focus:ring-4 focus:ring-brand-100/50;
}
.input-label {
@apply block mb-1.5 text-xs font-bold uppercase tracking-widest text-gray-500;
}
/* ── Premium Editorial Buttons Redesign ── */
.btn-primary {
@apply inline-flex items-center justify-center gap-2 rounded-xl bg-[#111827] px-5 py-3
text-sm font-bold text-white transition-all duration-300 ease-out shadow-sm
hover:bg-[#1f2937] hover:-translate-y-0.5 active:translate-y-0 active:scale-[0.98]
disabled:cursor-not-allowed disabled:opacity-40 disabled:translate-y-0;
}
.btn-ghost {
@apply inline-flex items-center justify-center gap-2 rounded-xl px-4 py-2.5
text-sm font-semibold text-gray-600 transition-all duration-200 ease-out
hover:bg-gray-100 hover:text-gray-900 active:scale-[0.98];
}
.btn-outline {
@apply inline-flex items-center justify-center gap-2 rounded-xl border border-gray-200/90
bg-white px-4 py-2.5 text-sm font-bold text-gray-700 transition-all duration-300 ease-out shadow-sm
hover:border-gray-300 hover:text-gray-900 hover:shadow-md hover:-translate-y-0.5 active:translate-y-0 active:scale-[0.98];
}
/* ── Badges Redesign ── */
.badge {
@apply inline-flex items-center rounded-full px-3 py-1 text-2xs font-bold uppercase tracking-wider;
}
.badge-brand { @apply badge bg-brand-50 text-brand-700 border border-brand-100/30; }
.badge-sage { @apply badge bg-sage-50 text-sage-700 border border-sage-100/30; }
.badge-neutral { @apply badge bg-gray-100 text-gray-600 border border-gray-200/50; }
/* ── Page Headings ── */
.page-heading { @apply font-display text-2xl font-extrabold tracking-tight text-gray-900 sm:text-3xl; }
.page-subtitle { @apply mt-1 text-sm text-gray-500; }
/* ── Mobile Data Tables ── */
.table-scroll { @apply overflow-x-auto overscroll-x-contain; -webkit-overflow-scrolling: touch; }
.data-table { @apply w-full text-left text-sm border-collapse; }
.data-table thead { @apply border-b border-gray-200 bg-gray-50/70; }
.data-table th { @apply px-5 py-4 text-xs font-bold uppercase tracking-wider text-gray-500 whitespace-nowrap; }
.data-table td { @apply px-5 py-4 text-gray-700 border-b border-gray-100 max-w-xs truncate; }
.data-table tbody tr { @apply transition-colors hover:bg-gray-50/50; }
/* ── Dividers ── */
.divider { @apply border-t border-gray-200/80; }
/* ── Backward Compatibility ── */
.surface-card { @apply card; }
.surface-card-elevated { @apply card-elevated; }
.field-input { @apply input-field; }
.field-label { @apply input-label; }
.amber-btn { @apply btn-outline; }
.amber-btn--solid { @apply btn-primary; }
.amber-btn--ghost { @apply btn-ghost; }
.neon-button { @apply btn-outline; }
.input-base { @apply input-field; }
.warm-divider { @apply divider; }
}
.episode-artwork-toggle {
background-color: var(--app-panel);
border-color: var(--app-border);
color: var(--app-subtle);
}
.episode-artwork-toggle--on,
.episode-artwork-toggle[data-state='on'] {
background-color: var(--app-brand-soft) !important;
border-color: var(--app-brand-border) !important;
color: var(--app-brand-text) !important;
}
.episode-artwork-toggle__icon,
.episode-artwork-toggle__state {
background-color: var(--app-panel-soft);
color: var(--app-muted);
}
.episode-artwork-toggle--on .episode-artwork-toggle__icon,
.episode-artwork-toggle--on .episode-artwork-toggle__state,
.episode-artwork-toggle[data-state='on'] .episode-artwork-toggle__icon,
.episode-artwork-toggle[data-state='on'] .episode-artwork-toggle__state {
background-color: var(--app-brand-emphasis) !important;
color: var(--app-brand-text) !important;
}
/* ── 播放器字幕(WebVTT <track>)──
彻底去除浏览器 User Agent 默认的半透明黑底背景框,使用文字阴影保证亮暗画面下的可读性。 */
::cue,
video::cue,
::cue(*),
video::cue(*) {
background: transparent !important;
background-color: transparent !important;
color: #ffffff !important;
font-family:
"PingFang SC",
"Microsoft YaHei",
"Noto Sans CJK SC",
"Source Han Sans SC",
sans-serif !important;
font-weight: 500 !important;
line-height: 1.35 !important;
text-shadow:
0 1px 3px rgba(0, 0, 0, 0.95),
0 0 8px rgba(0, 0, 0, 0.8),
0 0 16px rgba(0, 0, 0, 0.6) !important;
}
/* ── Entrance animations (replaces framer-motion on the critical shell) ── */
@keyframes overlay-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes drawer-in { from { transform: translateX(-100%); } to { transform: translateX(0); } }
@keyframes page-in { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } }
@keyframes accordion-in { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: translateY(0); } }
@keyframes fade-slide-in { from { opacity: 0; transform: translateX(-10px); } to { opacity: 1; transform: translateX(0); } }
@keyframes menu-in { from { opacity: 0; transform: translateY(10px) scale(0.95); } to { opacity: 1; transform: translateY(0) scale(1); } }
.animate-overlay-in { animation: overlay-in 0.15s ease-out both; }
.animate-drawer-in { animation: drawer-in 0.22s ease-out both; }
/* 播放完成后不能保留 transform,否则长页面会成为 fixed 弹框的包含块。 */
.animate-page-in { animation: page-in 0.25s ease-out backwards; }
.animate-accordion-in { animation: accordion-in 0.18s ease-out both; }
.animate-fade-slide-in { animation: fade-slide-in 0.2s ease-out both; }
.animate-menu-in { animation: menu-in 0.15s ease-out both; }
@media (prefers-reduced-motion: reduce) {
.animate-overlay-in,
.animate-drawer-in,
.animate-page-in,
.animate-accordion-in,
.animate-fade-slide-in,
.animate-menu-in { animation: none !important; }
}
@keyframes pulse-soft { 0%, 100% { opacity: 0.4; } 50% { opacity: 1; } }
@keyframes hero-in { from { opacity: 0; transform: scale(1.08); } to { opacity: 0.38; transform: scale(1.02); } }
@keyframes title-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
.animate-pulse-soft { animation: pulse-soft 1.5s ease-in-out infinite; }
.animate-hero-in { animation: hero-in 0.8s ease-out both; }
.animate-title-in { animation: title-in 0.3s ease-out both; }
@media (prefers-reduced-motion: reduce) {
.animate-pulse-soft,
.animate-hero-in,
.animate-title-in { animation: none !important; }
}