improvements
@@ -1,8 +1,12 @@
|
||||
@namespace Faraon.Client.Components
|
||||
@using Faraon.Core.AI
|
||||
|
||||
<div class="lobby-screen">
|
||||
<div class="lobby-container">
|
||||
<div class="lobby-header">
|
||||
<div class="lobby-logo-wrapper">
|
||||
<img src="assets/logo/logo_2_modern.jpg" class="lobby-logo-img" alt="FARAÓN Logo" />
|
||||
</div>
|
||||
<h1 class="lobby-title">FARAÓN</h1>
|
||||
<div class="lobby-subtitle">Tradičná mariášová kartová hra s moderným nábojom</div>
|
||||
</div>
|
||||
@@ -43,13 +47,14 @@
|
||||
<option value="@PlayerType.AI">🤖 AI Počítač</option>
|
||||
</select>
|
||||
|
||||
<!-- Obtiažnosť AI (ak je AI) -->
|
||||
<!-- Výber AI osobnosti a obtiažnosti (ak je AI) -->
|
||||
@if (p.Type == PlayerType.AI)
|
||||
{
|
||||
<select class="player-setup-select" @bind="p.Difficulty">
|
||||
<option value="@AIDifficulty.Easy">🌱 Začiatočník (Ľahký)</option>
|
||||
<option value="@AIDifficulty.Medium">⚔️ Taktik (Stredný)</option>
|
||||
<option value="@AIDifficulty.Hard">🔥 Veľmajster (Ťažký)</option>
|
||||
<select class="player-setup-select" style="font-weight: 700; color: var(--gold);" value="@(p.PersonalityId ?? "fox")" @onchange="(e) => SelectPersonality(idx, e.Value?.ToString())">
|
||||
@foreach (var pers in AIPersonality.All)
|
||||
{
|
||||
<option value="@pers.Id">@pers.BaseAvatar @pers.Name (@GetDiffLabel(pers.Difficulty))</option>
|
||||
}
|
||||
</select>
|
||||
}
|
||||
</div>
|
||||
@@ -255,9 +260,9 @@
|
||||
private List<Player> PlayerConfigs = new()
|
||||
{
|
||||
new Player("Ty (Hráč 1)", PlayerType.Human, "👑"),
|
||||
new Player("AI Jano", PlayerType.AI, "🦊", AIDifficulty.Medium),
|
||||
new Player("AI Zuzka", PlayerType.AI, "👸", AIDifficulty.Hard),
|
||||
new Player("AI Mišo", PlayerType.AI, "🤖", AIDifficulty.Easy)
|
||||
new Player(AIPersonality.Fox.Name, PlayerType.AI, AIPersonality.Fox.BaseAvatar, AIPersonality.Fox.Difficulty, AIPersonality.Fox.Id),
|
||||
new Player(AIPersonality.Queen.Name, PlayerType.AI, AIPersonality.Queen.BaseAvatar, AIPersonality.Queen.Difficulty, AIPersonality.Queen.Id),
|
||||
new Player(AIPersonality.Robot.Name, PlayerType.AI, AIPersonality.Robot.BaseAvatar, AIPersonality.Robot.Difficulty, AIPersonality.Robot.Id)
|
||||
};
|
||||
|
||||
private void SetPlayerCount(int count)
|
||||
@@ -272,10 +277,27 @@
|
||||
PlayerConfigs[index].Avatar = Avatars[nextIdx];
|
||||
}
|
||||
|
||||
private void SelectPersonality(int index, string? personalityId)
|
||||
{
|
||||
if (string.IsNullOrEmpty(personalityId)) return;
|
||||
var pers = AIPersonality.GetById(personalityId);
|
||||
PlayerConfigs[index].PersonalityId = pers.Id;
|
||||
PlayerConfigs[index].Name = pers.Name;
|
||||
PlayerConfigs[index].Avatar = pers.BaseAvatar;
|
||||
PlayerConfigs[index].Difficulty = pers.Difficulty;
|
||||
}
|
||||
|
||||
private string GetDiffLabel(AIDifficulty diff) => diff switch
|
||||
{
|
||||
AIDifficulty.Easy => "Ľahký",
|
||||
AIDifficulty.Hard => "Veľmajster",
|
||||
_ => "Taktik"
|
||||
};
|
||||
|
||||
private async Task StartGame()
|
||||
{
|
||||
var activePlayers = PlayerConfigs.Take(SelectedPlayerCount).Select(p =>
|
||||
new Player(p.Name, p.Type, p.Avatar, p.Difficulty)
|
||||
new Player(p.Name, p.Type, p.Avatar, p.Difficulty, p.PersonalityId)
|
||||
).ToList();
|
||||
|
||||
await OnStartGame.InvokeAsync((activePlayers, Rules));
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@namespace Faraon.Client.Components
|
||||
|
||||
<div class="player-slot @PositionClass @(IsFrozen ? "frozen-slot" : (IsCurrentTurn ? "active-turn-slot" : ""))">
|
||||
<div class="avatar-badge @(IsFrozen ? "is-frozen" : (IsCurrentTurn ? "active-turn" : "")) @(Player.HasFinished ? "is-finished" : "") @(CanBeRevived && Player.HasFinished && ReviveTurnsRemaining > 0 ? "can-be-revived" : "")">
|
||||
<div class="avatar-badge @(IsFrozen ? "is-frozen" : (IsCurrentTurn ? "active-turn" : "")) @(Player.HasFinished ? "is-finished" : "") @(CanBeRevived && Player.HasFinished && ReviveTurnsRemaining > 0 ? "can-be-revived" : "") emotion-aura-@Player.CurrentEmotion.ToString().ToLowerInvariant()">
|
||||
@if (IsFrozen && !Player.HasFinished && !Player.IsEliminated)
|
||||
{
|
||||
<div class="frozen-indicator-badge">
|
||||
@@ -24,7 +24,13 @@
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="avatar-icon">@Player.Avatar</div>
|
||||
<div class="avatar-icon-wrapper emotion-anim-@Player.CurrentEmotion.ToString().ToLowerInvariant()">
|
||||
<span class="avatar-icon">@Player.GetLiveAvatar()</span>
|
||||
@if (!Player.HasFinished && !Player.IsEliminated && Player.GetEmotionBadge() != null)
|
||||
{
|
||||
<span class="avatar-emotion-dot-badge">@Player.GetEmotionBadge()</span>
|
||||
}
|
||||
</div>
|
||||
<div class="avatar-name">
|
||||
@Player.Name
|
||||
@if (Player.Type == PlayerType.AI)
|
||||
|
||||
@@ -17,6 +17,7 @@ else
|
||||
<!-- Horná lišta -->
|
||||
<header class="game-header">
|
||||
<div style="display: flex; align-items: center; gap: 10px;">
|
||||
<img src="assets/logo/logo_2_modern.jpg" style="width: 34px; height: 34px; border-radius: 50%; border: 1.5px solid #00e5ff; object-fit: cover; box-shadow: 0 0 12px rgba(0,229,255,0.6);" alt="Logo" />
|
||||
<h1 class="game-title">FARAÓN</h1>
|
||||
@if (Engine.State.Rules.OlympicMode)
|
||||
{
|
||||
@@ -25,20 +26,21 @@ else
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; gap: 12px;">
|
||||
<div style="display: flex; align-items: center; gap: 8px;">
|
||||
<!-- Rýchlosť hry -->
|
||||
<button class="btn-speed-control" @onclick="CycleSpeed" title="Zmeniť rýchlosť hry">
|
||||
@GetSpeedButtonText(Engine.State.Rules.SpeedLevel)
|
||||
</button>
|
||||
|
||||
<!-- Zvuk -->
|
||||
<button class="btn-header-action" @onclick="ToggleMute" title="@(IsMuted ? "Zapnúť zvuk" : "Stlmiť zvuk")">
|
||||
@(IsMuted ? "🔇" : "🔊")
|
||||
<button class="btn-header-action @(IsMuted ? "btn-sound-muted" : "")" @onclick="ToggleMute" title="@(IsMuted ? "Zapnúť zvuk" : "Stlmiť zvuk")">
|
||||
<span>@(IsMuted ? "🔇" : "🔊")</span>
|
||||
</button>
|
||||
|
||||
<!-- Nová hra -->
|
||||
<!-- Menu -->
|
||||
<button class="btn-header-action" @onclick="ReturnToLobby" title="Späť do menu">
|
||||
⚙️ Menu
|
||||
<span style="font-size: 0.9rem;">⚙️</span>
|
||||
<span>Menu</span>
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
@@ -174,7 +176,7 @@ else
|
||||
}
|
||||
|
||||
<div style="display: flex; align-items: center; gap: 8px;">
|
||||
<span class="avatar-icon">@ViewingPlayer.Avatar</span>
|
||||
<span class="avatar-icon">@ViewingPlayer.GetLiveAvatar()</span>
|
||||
<span class="avatar-name">
|
||||
@ViewingPlayer.Name
|
||||
@if (ViewingPlayer.Type == PlayerType.AI)
|
||||
@@ -475,6 +477,40 @@ else
|
||||
}
|
||||
}
|
||||
|
||||
// Dynamické emócie hráčov na herné udalosti
|
||||
if (e.SourcePlayer != null)
|
||||
{
|
||||
switch (e.Type)
|
||||
{
|
||||
case GameEventType.AceSkipped:
|
||||
SetPlayerEmotion(e.SourcePlayer, PlayerEmotion.Freezing, 3500);
|
||||
break;
|
||||
case GameEventType.AceCountered:
|
||||
case GameEventType.SevenCanceled:
|
||||
SetPlayerEmotion(e.SourcePlayer, PlayerEmotion.Relieved, 3000);
|
||||
break;
|
||||
case GameEventType.CardsBurned:
|
||||
SetPlayerEmotion(e.SourcePlayer, PlayerEmotion.Confident, 3500);
|
||||
break;
|
||||
case GameEventType.PlayerFinished:
|
||||
case GameEventType.MatchWon:
|
||||
SetPlayerEmotion(e.SourcePlayer, PlayerEmotion.Celebrating, 10000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (e.TargetPlayer != null)
|
||||
{
|
||||
switch (e.Type)
|
||||
{
|
||||
case GameEventType.SevenStacked:
|
||||
SetPlayerEmotion(e.TargetPlayer, e.ExtraData >= 6 ? PlayerEmotion.Shocked : PlayerEmotion.Angry, 3500);
|
||||
break;
|
||||
case GameEventType.PlayerRevived:
|
||||
SetPlayerEmotion(e.TargetPlayer, PlayerEmotion.Confident, 3500);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Engine != null && Engine.State.CurrentPlayer.Hand.Count == 1 && !Engine.State.CurrentPlayer.HasFinished)
|
||||
{
|
||||
await Fx.PlayHeartbeatAsync();
|
||||
@@ -746,6 +782,27 @@ else
|
||||
var aiPlayer = Engine.State.CurrentPlayer;
|
||||
if (aiPlayer.Type != PlayerType.AI) return;
|
||||
|
||||
if (aiPlayer.Hand.Count <= 2)
|
||||
{
|
||||
SetPlayerEmotion(aiPlayer, PlayerEmotion.Confident, 3500);
|
||||
}
|
||||
else if (aiPlayer.Hand.Count >= 8)
|
||||
{
|
||||
SetPlayerEmotion(aiPlayer, PlayerEmotion.Desperate, 3500);
|
||||
}
|
||||
else if (Engine.State.PendingSkip)
|
||||
{
|
||||
SetPlayerEmotion(aiPlayer, PlayerEmotion.Freezing, 3500);
|
||||
}
|
||||
else if (Engine.State.PendingDrawCount > 0)
|
||||
{
|
||||
SetPlayerEmotion(aiPlayer, PlayerEmotion.Shocked, 3500);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetPlayerEmotion(aiPlayer, PlayerEmotion.Thinking, 3500);
|
||||
}
|
||||
|
||||
if (Engine.State.Rules.AIHumanMode)
|
||||
{
|
||||
string thought = AIDialogueService.GetThinkingDialogue(aiPlayer, Engine.State);
|
||||
@@ -962,6 +1019,25 @@ else
|
||||
});
|
||||
}
|
||||
|
||||
private void SetPlayerEmotion(Player player, PlayerEmotion emotion, int durationMs = 3000)
|
||||
{
|
||||
player.CurrentEmotion = emotion;
|
||||
StateHasChanged();
|
||||
|
||||
if (emotion != PlayerEmotion.Neutral && emotion != PlayerEmotion.Celebrating)
|
||||
{
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
await Task.Delay(durationMs);
|
||||
if (player.CurrentEmotion == emotion)
|
||||
{
|
||||
player.CurrentEmotion = PlayerEmotion.Neutral;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<(Player Player, string PositionClass)> GetOpponents()
|
||||
{
|
||||
if (Engine == null) return Enumerable.Empty<(Player, string)>();
|
||||
|
||||
|
After Width: | Height: | Size: 956 KiB |
|
After Width: | Height: | Size: 765 KiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 998 KiB |
|
After Width: | Height: | Size: 923 KiB |
|
After Width: | Height: | Size: 691 KiB |
@@ -57,32 +57,103 @@ body, html {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
/* App Loader */
|
||||
/* App Loader (WASM modern esports Pharaoh loader) */
|
||||
.app-loader {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
background: radial-gradient(circle at center, #1b4d3e 0%, #050b08 100%);
|
||||
background: radial-gradient(circle at center, #0f2b38 0%, #061118 60%, #02060a 100%);
|
||||
color: #ffffff;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.loader-card {
|
||||
font-size: 4rem;
|
||||
animation: bounce 1.2s infinite alternate ease-in-out;
|
||||
.loader-logo-container {
|
||||
position: relative;
|
||||
width: 140px;
|
||||
height: 140px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.loader-logo-img {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
border: 3px solid #00e5ff;
|
||||
box-shadow: 0 0 30px rgba(0, 229, 255, 0.6), 0 0 60px rgba(255, 215, 0, 0.3);
|
||||
animation: loader-pulse 2.2s infinite ease-in-out alternate;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.loader-spinner-ring {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 140px;
|
||||
height: 140px;
|
||||
border-radius: 50%;
|
||||
border: 3px solid transparent;
|
||||
border-top-color: #00e5ff;
|
||||
border-right-color: #ffd700;
|
||||
animation: loader-spin 1.4s linear infinite;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
@keyframes loader-spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
@keyframes loader-pulse {
|
||||
0% { transform: scale(0.96); box-shadow: 0 0 20px rgba(0, 229, 255, 0.5); }
|
||||
100% { transform: scale(1.04); box-shadow: 0 0 45px rgba(0, 229, 255, 0.85), 0 0 70px rgba(255, 215, 0, 0.4); }
|
||||
}
|
||||
|
||||
.loader-title {
|
||||
font-family: 'Cinzel', serif;
|
||||
font-size: 2.2rem;
|
||||
font-weight: 900;
|
||||
letter-spacing: 4px;
|
||||
color: var(--gold);
|
||||
text-shadow: 0 0 25px rgba(255, 215, 0, 0.7), 0 0 45px rgba(0, 229, 255, 0.5);
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.loader-text {
|
||||
margin-top: 1rem;
|
||||
font-family: 'Cinzel', serif;
|
||||
font-size: 1.5rem;
|
||||
letter-spacing: 2px;
|
||||
color: var(--gold);
|
||||
font-family: 'Outfit', sans-serif;
|
||||
font-size: 1.05rem;
|
||||
color: #94a3b8;
|
||||
letter-spacing: 1px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
@keyframes bounce {
|
||||
0% { transform: translateY(0) rotate(-5deg); }
|
||||
100% { transform: translateY(-20px) rotate(5deg); }
|
||||
.loader-progress-bar {
|
||||
width: 240px;
|
||||
height: 6px;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
border: 1px solid rgba(0, 229, 255, 0.3);
|
||||
}
|
||||
|
||||
.loader-progress-fill {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, #00e5ff, #ffd700, #00e5ff);
|
||||
background-size: 200% 100%;
|
||||
animation: loader-progress-anim 1.8s infinite linear;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
@keyframes loader-progress-anim {
|
||||
0% { background-position: 200% 0; }
|
||||
100% { background-position: -200% 0; }
|
||||
}
|
||||
|
||||
/* MAIN GAME CONTAINER */
|
||||
@@ -135,45 +206,63 @@ body, html {
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.btn-game-icon {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
color: #fff;
|
||||
border-radius: 50%;
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
font-size: 1.1rem;
|
||||
/* Top Game Header Controls */
|
||||
.btn-header-action,
|
||||
.btn-speed-control {
|
||||
display: inline-flex !important;
|
||||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
gap: 6px !important;
|
||||
height: 32px !important;
|
||||
padding: 0 14px !important;
|
||||
border-radius: 18px !important;
|
||||
font-family: 'Outfit', sans-serif !important;
|
||||
font-size: 0.85rem !important;
|
||||
font-weight: 700 !important;
|
||||
color: #e2e8f0 !important;
|
||||
background: rgba(10, 25, 20, 0.85) !important;
|
||||
border: 1.5px solid rgba(245, 176, 65, 0.45) !important;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.5), inset 0 1px 1px rgba(255, 255, 255, 0.1) !important;
|
||||
backdrop-filter: blur(8px) !important;
|
||||
cursor: pointer !important;
|
||||
transition: all 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275) !important;
|
||||
user-select: none !important;
|
||||
text-decoration: none !important;
|
||||
white-space: nowrap !important;
|
||||
outline: none !important;
|
||||
line-height: 1 !important;
|
||||
}
|
||||
|
||||
.btn-game-icon:hover {
|
||||
background: rgba(245, 176, 65, 0.3);
|
||||
border-color: var(--gold);
|
||||
transform: scale(1.1);
|
||||
.btn-header-action:hover,
|
||||
.btn-speed-control:hover {
|
||||
background: rgba(245, 176, 65, 0.25) !important;
|
||||
border-color: var(--gold) !important;
|
||||
color: #ffffff !important;
|
||||
box-shadow: 0 0 14px rgba(245, 176, 65, 0.55), 0 4px 12px rgba(0, 0, 0, 0.6) !important;
|
||||
transform: translateY(-2px) scale(1.04) !important;
|
||||
}
|
||||
|
||||
.btn-header-action:active,
|
||||
.btn-speed-control:active {
|
||||
transform: translateY(0) scale(0.97) !important;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.5) !important;
|
||||
}
|
||||
|
||||
.btn-speed-control {
|
||||
width: auto !important;
|
||||
min-width: 60px;
|
||||
padding: 0 10px;
|
||||
border-radius: 20px !important;
|
||||
font-size: 0.8rem !important;
|
||||
font-weight: 800;
|
||||
letter-spacing: 0.3px;
|
||||
background: rgba(245, 176, 65, 0.15) !important;
|
||||
border-color: rgba(245, 176, 65, 0.45) !important;
|
||||
color: var(--gold) !important;
|
||||
white-space: nowrap;
|
||||
font-weight: 800 !important;
|
||||
letter-spacing: 0.3px !important;
|
||||
}
|
||||
|
||||
.btn-speed-control:hover {
|
||||
background: rgba(245, 176, 65, 0.35) !important;
|
||||
border-color: var(--gold) !important;
|
||||
box-shadow: 0 0 10px rgba(245, 176, 65, 0.4);
|
||||
.btn-header-action.btn-sound-muted {
|
||||
border-color: rgba(239, 68, 68, 0.5) !important;
|
||||
color: #f87171 !important;
|
||||
}
|
||||
|
||||
.btn-header-action.btn-sound-muted:hover {
|
||||
border-color: #ef4444 !important;
|
||||
background: rgba(239, 68, 68, 0.22) !important;
|
||||
box-shadow: 0 0 14px rgba(239, 68, 68, 0.55) !important;
|
||||
}
|
||||
|
||||
/* TABLE FELT & SLOTS */
|
||||
@@ -405,9 +494,134 @@ body, html {
|
||||
100% { transform: translate(-50%, -50%) scale(1.25); }
|
||||
}
|
||||
|
||||
.avatar-icon-wrapper {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
||||
}
|
||||
|
||||
.avatar-icon {
|
||||
font-size: 2.5rem;
|
||||
line-height: 1;
|
||||
display: inline-block;
|
||||
transition: transform 0.25s ease;
|
||||
}
|
||||
|
||||
.avatar-emotion-dot-badge {
|
||||
position: absolute;
|
||||
bottom: -4px;
|
||||
right: -10px;
|
||||
font-size: 1.15rem;
|
||||
filter: drop-shadow(0 2px 5px rgba(0, 0, 0, 0.85));
|
||||
animation: badge-pop 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
||||
z-index: 15;
|
||||
}
|
||||
|
||||
@keyframes badge-pop {
|
||||
0% { transform: scale(0) rotate(-15deg); opacity: 0; }
|
||||
100% { transform: scale(1) rotate(0deg); opacity: 1; }
|
||||
}
|
||||
|
||||
/* AVATAR EMOTION MICRO-ANIMATIONS */
|
||||
.emotion-anim-thinking {
|
||||
animation: anim-thinking 1.8s ease-in-out infinite alternate;
|
||||
}
|
||||
|
||||
@keyframes anim-thinking {
|
||||
0% { transform: translateY(0) rotate(-2deg); }
|
||||
100% { transform: translateY(-4px) rotate(3deg); }
|
||||
}
|
||||
|
||||
.emotion-anim-confident {
|
||||
animation: anim-confident 1.4s ease-in-out infinite alternate;
|
||||
}
|
||||
|
||||
@keyframes anim-confident {
|
||||
0% { transform: scale(1); }
|
||||
100% { transform: scale(1.14); }
|
||||
}
|
||||
|
||||
.emotion-anim-shocked {
|
||||
animation: anim-shocked 0.35s ease-in-out infinite alternate;
|
||||
}
|
||||
|
||||
@keyframes anim-shocked {
|
||||
0% { transform: translateX(-4px) scale(1.1); }
|
||||
100% { transform: translateX(4px) scale(1.1); }
|
||||
}
|
||||
|
||||
.emotion-anim-freezing {
|
||||
animation: anim-freezing 0.12s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes anim-freezing {
|
||||
0% { transform: translate(-2px, -1px); }
|
||||
50% { transform: translate(2px, 1px); }
|
||||
100% { transform: translate(-1px, 2px); }
|
||||
}
|
||||
|
||||
.emotion-anim-angry {
|
||||
animation: anim-angry 0.22s ease-in-out infinite alternate;
|
||||
}
|
||||
|
||||
@keyframes anim-angry {
|
||||
0% { transform: rotate(-5deg) scale(1.06); }
|
||||
100% { transform: rotate(5deg) scale(1.06); }
|
||||
}
|
||||
|
||||
.emotion-anim-relieved {
|
||||
animation: anim-relieved 1.4s ease-in-out infinite alternate;
|
||||
}
|
||||
|
||||
@keyframes anim-relieved {
|
||||
0% { transform: translateY(0); }
|
||||
100% { transform: translateY(-3px); }
|
||||
}
|
||||
|
||||
.emotion-anim-desperate {
|
||||
animation: anim-desperate 1.8s ease-in-out infinite alternate;
|
||||
}
|
||||
|
||||
@keyframes anim-desperate {
|
||||
0% { transform: translateY(0) scale(0.95); }
|
||||
100% { transform: translateY(4px) scale(0.88); }
|
||||
}
|
||||
|
||||
.emotion-anim-celebrating {
|
||||
animation: anim-celebrating 0.6s cubic-bezier(0.175, 0.885, 0.32, 1.275) infinite alternate;
|
||||
}
|
||||
|
||||
@keyframes anim-celebrating {
|
||||
0% { transform: translateY(0) rotate(-7deg) scale(1.1); }
|
||||
100% { transform: translateY(-8px) rotate(7deg) scale(1.22); }
|
||||
}
|
||||
|
||||
/* EMOTION AURAS ON AVATAR BADGE */
|
||||
.avatar-badge.emotion-aura-angry {
|
||||
border-color: #ef4444 !important;
|
||||
box-shadow: 0 0 25px rgba(239, 68, 68, 0.85), inset 0 0 14px rgba(239, 68, 68, 0.4) !important;
|
||||
}
|
||||
|
||||
.avatar-badge.emotion-aura-shocked {
|
||||
border-color: #f59e0b !important;
|
||||
box-shadow: 0 0 25px rgba(245, 158, 11, 0.85), inset 0 0 14px rgba(245, 158, 11, 0.4) !important;
|
||||
}
|
||||
|
||||
.avatar-badge.emotion-aura-confident {
|
||||
border-color: #eab308 !important;
|
||||
box-shadow: 0 0 25px rgba(234, 179, 8, 0.85), inset 0 0 14px rgba(234, 179, 8, 0.4) !important;
|
||||
}
|
||||
|
||||
.avatar-badge.emotion-aura-celebrating {
|
||||
border-color: #ffd700 !important;
|
||||
box-shadow: 0 0 35px rgba(255, 215, 0, 1), inset 0 0 20px rgba(255, 215, 0, 0.6) !important;
|
||||
}
|
||||
|
||||
.avatar-badge.emotion-aura-relieved {
|
||||
border-color: #22c55e !important;
|
||||
box-shadow: 0 0 25px rgba(34, 197, 94, 0.85), inset 0 0 14px rgba(34, 197, 94, 0.4) !important;
|
||||
}
|
||||
|
||||
.avatar-name {
|
||||
@@ -1557,6 +1771,27 @@ body, html {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.lobby-logo-wrapper {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.lobby-logo-img {
|
||||
width: 96px;
|
||||
height: 96px;
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
border: 3px solid #00e5ff;
|
||||
box-shadow: 0 0 25px rgba(0, 229, 255, 0.65), 0 0 45px rgba(255, 215, 0, 0.35), 0 8px 24px rgba(0, 0, 0, 0.85);
|
||||
animation: logo-glow 3s infinite ease-in-out alternate;
|
||||
}
|
||||
|
||||
@keyframes logo-glow {
|
||||
0% { transform: scale(1); box-shadow: 0 0 20px rgba(0, 229, 255, 0.5), 0 0 35px rgba(255, 215, 0, 0.25); }
|
||||
100% { transform: scale(1.05); box-shadow: 0 0 40px rgba(0, 229, 255, 0.9), 0 0 60px rgba(255, 215, 0, 0.5); }
|
||||
}
|
||||
|
||||
.lobby-title {
|
||||
font-family: 'Cinzel', serif;
|
||||
font-size: 2.5rem;
|
||||
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 765 KiB |
@@ -11,15 +11,23 @@
|
||||
<link href="https://fonts.googleapis.com/css2?family=Cinzel:wght@600;800;900&family=Outfit:wght@400;600;700;900&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="lib/bootstrap/dist/css/bootstrap.min.css" />
|
||||
<link rel="stylesheet" href="css/app.css" />
|
||||
<link rel="icon" type="image/png" href="favicon.png" />
|
||||
<link rel="icon" type="image/jpeg" href="assets/logo/logo_2_modern.jpg" />
|
||||
<link rel="apple-touch-icon" href="assets/logo/logo_2_modern.jpg" />
|
||||
<link href="Faraon.Client.styles.css" rel="stylesheet" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app">
|
||||
<div class="app-loader">
|
||||
<div class="loader-card">🃏</div>
|
||||
<div class="loader-text">Načítavam Faraóna...</div>
|
||||
<div class="loader-logo-container">
|
||||
<img src="assets/logo/logo_2_modern.jpg" class="loader-logo-img" alt="FARAÓN" />
|
||||
<div class="loader-spinner-ring"></div>
|
||||
</div>
|
||||
<div class="loader-title">FARAÓN</div>
|
||||
<div class="loader-text">Pripravujem stôl a miešam karty...</div>
|
||||
<div class="loader-progress-bar">
|
||||
<div class="loader-progress-fill"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||