278 lines
7.8 KiB
CSS
278 lines
7.8 KiB
CSS
/* css/main.css */
|
|
|
|
/* 背景图案生成 */
|
|
.bg-desktop-pattern {
|
|
background-image: radial-gradient(circle at 1px 1px, #334155 1px, transparent 0);
|
|
background-size: 24px 24px;
|
|
}
|
|
|
|
/* 隐藏滚动条 */
|
|
::-webkit-scrollbar {
|
|
display: none;
|
|
}
|
|
|
|
/* 卡片基础样式 - 核心交互与视觉 */
|
|
.game-card, .stack-group {
|
|
width: 170px;
|
|
height: 240px;
|
|
position: absolute;
|
|
border-radius: 14px;
|
|
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.4), 0 4px 6px -2px rgba(0, 0, 0, 0.2);
|
|
transition: transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 0.25s ease;
|
|
display: flex;
|
|
flex-direction: column;
|
|
overflow: visible; /* 允许进度条等元素溢出 */
|
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
cursor: grab;
|
|
background-color: #1e293b;
|
|
color: #f8fafc;
|
|
will-change: transform, left, top;
|
|
}
|
|
|
|
/* 正在被拖拽的状态 */
|
|
.game-card.dragging, .stack-group.dragging {
|
|
cursor: grabbing;
|
|
transform: scale(1.08) rotate(2deg) translateY(-5px);
|
|
box-shadow: 0 25px 35px -5px rgba(0, 0, 0, 0.5), 0 10px 15px -5px rgba(0, 0, 0, 0.3);
|
|
z-index: 100 !important;
|
|
transition: none; /* 拖拽时取消缓动动画,跟随鼠标更紧密 */
|
|
}
|
|
|
|
/* 悬停时的微动效 */
|
|
.game-card:hover:not(.dragging), .stack-group:hover:not(.dragging) {
|
|
transform: translateY(-4px) scale(1.02);
|
|
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.4), 0 10px 10px -5px rgba(0, 0, 0, 0.2);
|
|
z-index: 50;
|
|
}
|
|
|
|
/* 卡牌内部结构 */
|
|
.card-header {
|
|
padding: 10px 14px;
|
|
font-size: 13px;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
border-bottom: 1px solid rgba(255,255,255,0.08);
|
|
border-radius: 14px 14px 0 0;
|
|
backdrop-filter: blur(4px);
|
|
}
|
|
|
|
.card-body {
|
|
flex: 1;
|
|
padding: 14px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
background: linear-gradient(to bottom, rgba(0,0,0,0) 0%, rgba(0,0,0,0.2) 100%);
|
|
}
|
|
|
|
.card-footer {
|
|
padding: 10px 12px;
|
|
font-size: 11px;
|
|
display: flex;
|
|
gap: 6px;
|
|
flex-wrap: wrap;
|
|
border-top: 1px solid rgba(255,255,255,0.08);
|
|
background: rgba(0,0,0,0.3);
|
|
border-radius: 0 0 14px 14px;
|
|
}
|
|
|
|
.tag {
|
|
background: rgba(255,255,255,0.1);
|
|
padding: 3px 8px;
|
|
border-radius: 6px;
|
|
color: #cbd5e1;
|
|
font-weight: 500;
|
|
box-shadow: inset 0 1px 0 rgba(255,255,255,0.1);
|
|
}
|
|
|
|
/* ================= 职业卡系主题 ================= */
|
|
|
|
/* 实体角色 (Actor) */
|
|
.card-actor {
|
|
background: linear-gradient(145deg, #1e3a8a, #1d4ed8);
|
|
border-color: rgba(59, 130, 246, 0.5);
|
|
box-shadow: 0 0 15px rgba(29, 78, 216, 0.2);
|
|
}
|
|
|
|
/* 资源卡 (Resource) */
|
|
.card-resource {
|
|
background: linear-gradient(145deg, #064e3b, #047857);
|
|
border-color: rgba(16, 185, 129, 0.4);
|
|
}
|
|
|
|
/* 负面卡 (Negative) */
|
|
.card-negative {
|
|
background: linear-gradient(145deg, #4c1d95, #6d28d9);
|
|
border-color: rgba(139, 92, 246, 0.4);
|
|
}
|
|
|
|
/* 目标模块卡 (Module) */
|
|
.card-module {
|
|
background: linear-gradient(145deg, #78350f, #92400e);
|
|
border-color: rgba(245, 158, 11, 0.5);
|
|
}
|
|
|
|
/* 危机预警卡 (Warning) */
|
|
.card-warning {
|
|
background: linear-gradient(145deg, #450a0a, #7f1d1d);
|
|
border-color: rgba(239, 68, 68, 0.6);
|
|
animation: pulse-border 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
|
}
|
|
|
|
/* 危机爆发卡 (Crisis) */
|
|
.card-crisis {
|
|
background: linear-gradient(145deg, #2a0808, #5a1010);
|
|
border-color: #f87171;
|
|
box-shadow: 0 0 30px rgba(239, 68, 68, 0.4);
|
|
}
|
|
|
|
@keyframes pulse-border {
|
|
0%, 100% {
|
|
border-color: rgba(239, 68, 68, 0.3);
|
|
box-shadow: 0 0 15px rgba(239, 68, 68, 0.2);
|
|
}
|
|
50% {
|
|
border-color: rgba(239, 68, 68, 0.9);
|
|
box-shadow: 0 0 25px rgba(239, 68, 68, 0.6);
|
|
}
|
|
}
|
|
|
|
/* ================= 组件 ================= */
|
|
|
|
/* 进度条 (Processing Bar) */
|
|
.progress-container {
|
|
position: absolute;
|
|
top: -18px;
|
|
left: 50%;
|
|
transform: translateX(-50%);
|
|
width: 110%;
|
|
height: 14px;
|
|
background: #0f172a;
|
|
border-radius: 8px;
|
|
border: 2px solid #334155;
|
|
overflow: hidden;
|
|
z-index: 20;
|
|
box-shadow: 0 4px 6px rgba(0,0,0,0.5);
|
|
}
|
|
|
|
.progress-bar {
|
|
height: 100%;
|
|
background: linear-gradient(90deg, #3b82f6, #60a5fa);
|
|
border-radius: 6px;
|
|
box-shadow: inset 0 2px 4px rgba(255,255,255,0.3);
|
|
transition: width 0.1s linear;
|
|
}
|
|
|
|
/* 危机槽位 (Slots) */
|
|
.crisis-slot {
|
|
width: 44px;
|
|
height: 44px;
|
|
border: 2px dashed rgba(255,255,255,0.2);
|
|
border-radius: 8px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 22px;
|
|
background: rgba(0,0,0,0.3);
|
|
transition: all 0.2s;
|
|
}
|
|
|
|
.crisis-slot:hover {
|
|
border-color: rgba(255,255,255,0.5);
|
|
background: rgba(255,255,255,0.05);
|
|
}
|
|
|
|
.crisis-slot.filled {
|
|
border: 2px solid #10b981;
|
|
background: rgba(16, 185, 129, 0.2);
|
|
box-shadow: 0 0 15px rgba(16, 185, 129, 0.3);
|
|
}
|
|
|
|
/* Loading 动画 (API Requesting) */
|
|
.loader {
|
|
border: 4px solid rgba(255,255,255,0.05);
|
|
border-top: 4px solid #f87171;
|
|
border-radius: 50%;
|
|
width: 42px;
|
|
height: 42px;
|
|
animation: spin 1s linear infinite;
|
|
box-shadow: 0 0 15px rgba(248, 113, 113, 0.2);
|
|
}
|
|
|
|
@keyframes spin {
|
|
0% { transform: rotate(0deg); }
|
|
100% { transform: rotate(360deg); }
|
|
}
|
|
|
|
/* 栈 (Stack Group) 调整,取消单独卡牌样式因为外层是一个容器 */
|
|
.stack-group {
|
|
background: transparent;
|
|
border: none;
|
|
box-shadow: none;
|
|
}
|
|
|
|
/* Stack Group 内的卡牌取消自身悬停动效以防止冲突 */
|
|
.stack-group .game-card {
|
|
position: absolute;
|
|
transition: none;
|
|
}
|
|
|
|
.stack-group .game-card:hover {
|
|
transform: none;
|
|
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.4);
|
|
}
|
|
|
|
/* 高亮可连接卡牌 (Highlight Connectable) */
|
|
.highlight-connectable {
|
|
box-shadow: 0 0 20px 5px rgba(59, 130, 246, 0.6) !important;
|
|
border-color: #60a5fa !important;
|
|
transform: scale(1.05);
|
|
z-index: 80;
|
|
}
|
|
|
|
/* 新卡牌生成弹现动效 */
|
|
@keyframes card-spawn {
|
|
0% { transform: scale(0) translateY(-20px); opacity: 0; filter: blur(10px); }
|
|
60% { transform: scale(1.05) translateY(5px); opacity: 1; filter: blur(0); }
|
|
100% { transform: scale(1) translateY(0); opacity: 1; filter: blur(0); }
|
|
}
|
|
|
|
/* 正在被连线悬停 (Hovering Connection Target) */
|
|
@keyframes magnetic-fusion {
|
|
0% { transform: scale(1.1) rotate(0deg); box-shadow: 0 0 60px 20px rgba(59,130,246,0.9), inset 0 0 20px rgba(59,130,246,0.8); border-color: #60a5fa; filter: brightness(1.2); }
|
|
33% { transform: scale(0.9) rotate(-3deg); box-shadow: 0 0 80px 30px rgba(139,92,246,0.9), inset 0 0 30px rgba(139,92,246,0.8); border-color: #c084fc; filter: brightness(1.5); }
|
|
66% { transform: scale(1.1) rotate(3deg); box-shadow: 0 0 80px 30px rgba(236,72,153,0.9), inset 0 0 30px rgba(236,72,153,0.8); border-color: #f472b6; filter: brightness(1.5); }
|
|
100% { transform: scale(1.1) rotate(0deg); box-shadow: 0 0 60px 20px rgba(59,130,246,0.9), inset 0 0 20px rgba(59,130,246,0.8); border-color: #60a5fa; filter: brightness(1.2); }
|
|
}
|
|
|
|
.highlight-hover {
|
|
animation: magnetic-fusion 0.6s infinite ease-in-out !important;
|
|
border-width: 3px !important;
|
|
z-index: 90 !important;
|
|
}
|
|
|
|
/* 危机卡悬停解救 (Hovering Crisis Resolution) */
|
|
@keyframes crisis-resolve-hover {
|
|
0%, 100% { transform: scale(1.15); box-shadow: 0 0 100px 40px rgba(16, 185, 129, 0.8); border-color: #34d399; filter: brightness(2) saturate(2); }
|
|
50% { transform: scale(1.05); box-shadow: 0 0 60px 20px rgba(16, 185, 129, 0.6); border-color: #10b981; filter: brightness(1.5) saturate(1.5); }
|
|
}
|
|
|
|
.highlight-crisis-hover {
|
|
animation: crisis-resolve-hover 0.5s infinite ease-in-out !important;
|
|
border-width: 4px !important;
|
|
z-index: 95 !important;
|
|
}
|
|
|
|
/* 连线 SVG 画布 */
|
|
#svg-connections {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
pointer-events: none;
|
|
z-index: 10;
|
|
}
|