bc/public/style_alt.css

1684 lines
49 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* === style_alt.css === */
/* Подключение внешних шрифтов и иконок */
@import url('https://fonts.googleapis.com/css2?family=MedievalSharp&family=Roboto:wght@300;400;700&display=swap');
@import url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css');
:root {
/* --- Переменные цветов и шрифтов --- */
--font-main: 'Roboto', sans-serif;
--font-fancy: 'MedievalSharp', cursive;
--bg-gradient-dark: linear-gradient(160deg, #1f243a, #10121c); /* Темный фон */
--panel-bg: rgba(16, 18, 28, 0.8); /* Фон панелей с прозрачностью */
--panel-border: #4a5072; /* Цвет рамки панелей */
/* Цвета свечения панелей (используются в JS анимации каста и в базовой тени) */
--panel-glow-player: rgba(80, 150, 255, 0.3); /* Для Елены (синее) */
--panel-glow-opponent: rgba(255, 80, 80, 0.3); /* Для Баларда (красное) */
--panel-glow-almagest: rgba(199, 108, 255, 0.3); /* Для Альмагест (фиолетовое) */
--text-light: #e8effc; /* Светлый основной текст */
--text-muted: #9badce; /* Приглушенный текст (подзаголовки, иконки по умолчанию) */
--text-heading: #ffffff; /* Белый текст заголовков */
/* Акцентные цвета персонажей (для имен, иконок, рамок) */
--accent-player: #6c95ff; /* Елена (светло-синий) */
--accent-opponent: #ff6c6c; /* Балард (красный) */
--accent-almagest: #c76cff; /* Альмагест (фиолетовый) */
/* Цвета полос характеристик */
--hp-color: #de4b4b; /* Здоровье (красный) */
--mana-color: #58a8d0; /* Мана Елены (голубой) */
--stamina-color: #ffb347; /* Ярость Баларда (оранжевый) */
--dark-energy-color: #ab47bc; /* Темная Энергия Альмагест (пурпурный) */
--bar-bg: #252a44; /* Фон полос */
/* Цвета кнопок */
--button-bg: linear-gradient(145deg, #556190, #3f4a70); /* Градиент фона кнопок */
--button-hover-bg: linear-gradient(145deg, #6a79b0, #556190); /* Градиент при наведении */
--button-text: var(--text-light); /* Цвет текста кнопок */
--button-ability-bg: linear-gradient(145deg, #305a5e, #1f4043); /* Фон кнопок способностей (темно-зеленый) */
--button-ability-hover-bg: linear-gradient(145deg, #407a7e, #305a5e); /* При наведении */
--button-ability-border: #4db0b5; /* Цвет рамки кнопок способностей (бирюзовый) */
--button-disabled-bg: #333950; /* Фон отключенных кнопок (темно-серый) */
--button-disabled-text: #6b7491; /* Цвет текста отключенных кнопок (светло-серый) */
/* Цвета лога боя */
--log-bg: rgba(10, 12, 20, 0.85); /* Фон лога */
--log-border: var(--panel-border); /* Рамка лога */
--log-text: var(--text-muted); /* Цвет текста лога */
/* Цвета сообщений в логе и элементов UI */
--icon-color: var(--text-muted); /* Цвет иконок по умолчанию */
--damage-color: #ff8080; /* Цвет урона (красноватый) */
--heal-color: #90ee90; /* Цвет лечения (светло-зеленый) */
--block-color: #add8e6; /* Цвет блока (светло-синий) */
--effect-color: #d8bfd8; /* Цвет эффектов (светло-фиолетовый) */
--turn-color: #ffd700; /* Цвет индикатора хода (золотой) */
--system-color: #7fffd4; /* Цвет системных сообщений (аквамариновый) */
/* Стили модального окна */
--modal-bg: rgba(16, 18, 28, 0.97); /* Фон модального оверлея */
--modal-content-bg: #2a2f45; /* Фон контента модального окна */
/* Стили скроллбара */
--scrollbar-thumb: #4a5072; /* Цвет ползунка скроллбара */
--scrollbar-track: #10121c; /* Цвет трека скроллбара */
/* Длительности анимаций (для JS) */
--shake-duration: 0.4s; /* Длительность анимации тряски */
--cast-duration: 0.6s; /* Длительность анимации каста */
--dissolve-duration: 6.0s; /* Длительность анимации растворения */
/* Фиксированная высота лог-панели (для десктопа) */
--log-panel-fixed-height: 280px;
}
/* --- Базовые Стили и Сброс --- */
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html {
height: 100%;
}
body {
font-family: var(--font-main);
background: var(--bg-gradient-dark) fixed; /* Фиксированный фон */
color: var(--text-light);
line-height: 1.5;
height: 100vh;
overflow: hidden; /* Предотвращает прокрутку основного body */
display: flex;
flex-direction: column;
align-items: center;
justify-content: center; /* Центрирует контент в body */
padding: 10px;
}
h1, h2, h3, h4 {
font-family: var(--font-fancy);
color: var(--text-heading);
margin-bottom: 0.75em;
font-weight: normal;
}
button {
font-family: var(--font-main);
}
i {
margin-right: 6px;
color: var(--icon-color);
width: 1.2em;
text-align: center;
}
/* Стили скроллбара (применяются ко всем элементам с overflow) */
* {
scrollbar-width: thin;
scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track);
}
*::-webkit-scrollbar {
width: 8px;
}
*::-webkit-scrollbar-track {
background: var(--scrollbar-track);
border-radius: 4px;
}
*::-webkit-scrollbar-thumb {
background-color: var(--scrollbar-thumb);
border-radius: 4px;
border: 2px solid var(--scrollbar-track);
}
/* === Стили для Экранов Аутентификации и Настройки Игры === */
.auth-game-setup-wrapper {
width: 100%;
max-width: 700px;
margin: 20px auto;
padding: 25px 30px;
background: var(--panel-bg);
border: 1px solid var(--panel-border);
border-radius: 10px;
box-shadow: 0 5px 20px rgba(0, 0, 0, 0.5);
color: var(--text-light);
text-align: center;
/* Добавим overflow-y: auto для случаев, когда контент не помещается */
max-height: calc(100vh - 40px); /* Чтобы не вылезал за экран */
overflow-y: auto;
}
.auth-game-setup-wrapper h2,
.auth-game-setup-wrapper h3 {
font-family: var(--font-fancy);
color: var(--text-heading);
margin-bottom: 1em;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
padding-bottom: 0.5em;
}
.auth-game-setup-wrapper h3 {
font-size: 1.2em;
margin-top: 1.5em;
}
/* Общие стили для кнопок в .auth-game-setup-wrapper и форм аутентификации */
.auth-game-setup-wrapper button,
#auth-section form button {
font-family: var(--font-main);
background: var(--button-bg);
color: var(--button-text);
border: 1px solid rgba(0, 0, 0, 0.3);
border-radius: 6px;
padding: 10px 18px;
margin: 8px 5px;
cursor: pointer;
transition: all 0.15s ease;
font-weight: bold;
text-transform: uppercase;
letter-spacing: 0.5px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
outline: none; /* Убираем синюю обводку при фокусе */
}
.auth-game-setup-wrapper button:hover:enabled,
#auth-section form button:hover:enabled {
background: var(--button-hover-bg);
transform: translateY(-2px) scale(1.02);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.4);
}
.auth-game-setup-wrapper button:active:enabled,
#auth-section form button:active:enabled {
transform: translateY(0px) scale(1);
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
}
.auth-game-setup-wrapper button:disabled,
#auth-section form button:disabled {
background: var(--button-disabled-bg) !important; /* Перебиваем градиент фоном */
color: var(--button-disabled-text) !important; /* Перебиваем цвет текста */
border-color: transparent !important; /* Убираем рамку */
cursor: not-allowed !important;
opacity: 0.7;
transform: none !important;
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.4) !important; /* Внутренняя тень для дизейбленого вида */
filter: grayscale(50%); /* Делаем серым */
}
/* Стили для инпутов */
.auth-game-setup-wrapper input[type="text"],
#auth-section input[type="text"],
#auth-section input[type="password"] {
padding: 10px;
border-radius: 5px;
border: 1px solid var(--panel-border);
background-color: var(--bar-bg);
color: var(--text-light);
margin: 5px 5px 10px 5px;
font-size: 0.9em;
width: calc(100% - 22px); /* Учитываем padding и border */
max-width: 300px;
box-sizing: border-box;
outline: none; /* Убираем синюю обводку при фокусе */
transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
.auth-game-setup-wrapper input[type="text"]:focus,
#auth-section input[type="text"]:focus,
#auth-section input[type="password"]:focus {
border-color: var(--accent-player); /* Подсветка при фокусе */
box-shadow: 0 0 8px rgba(108, 149, 255, 0.4);
}
/* Стили для списка доступных игр */
#available-games-list {
margin-top: 20px;
text-align: left;
max-height: 250px;
overflow-y: auto;
padding: 10px 15px;
background-color: rgba(0, 0, 0, 0.25);
border: 1px solid var(--log-border);
border-radius: 6px;
}
#available-games-list h3 {
margin-top: 0;
margin-bottom: 10px;
padding-bottom: 5px;
border-bottom: 1px dashed rgba(255, 255, 255, 0.1);
}
#available-games-list ul {
list-style: none;
padding: 0;
margin: 0;
}
#available-games-list li {
padding: 10px;
border-bottom: 1px solid rgba(74, 80, 114, 0.5); /* Полупрозрачная граница */
display: flex;
justify-content: space-between;
align-items: center;
font-size: 0.9em;
}
#available-games-list li:last-child {
border-bottom: none;
}
#available-games-list li button {
padding: 6px 10px;
font-size: 0.8em;
margin-left: 10px;
flex-shrink: 0; /* Не сжимать кнопку */
}
/* Контейнер для статусных сообщений (аутентификация и игра) */
#status-container {
min-height: 2.5em;
margin-bottom: 15px;
}
#auth-message,
#game-status-message {
font-weight: bold;
font-size: 1.1em;
padding: 5px;
background-color: rgba(0, 0, 0, 0.1);
border-radius: 4px;
display: block;
margin-bottom: 5px;
text-align: center;
}
#auth-message.success {
color: var(--heal-color);
}
#auth-message.error {
color: var(--damage-color);
}
#game-status-message {
color: var(--turn-color); /* Цвет для игрового статуса */
}
/* Формы аутентификации */
#auth-section form {
margin-bottom: 20px;
}
/* Информация о пользователе */
#user-info {
padding: 10px;
background-color: rgba(255, 255, 255, 0.05);
border-radius: 5px;
margin-bottom: 20px;
}
#user-info p {
margin: 0 0 10px 0;
font-size: 1.1em;
}
#logout-button {
/* Стили для кнопки выхода (темно-красный) */
background: linear-gradient(145deg, #8c3a3a, #6b2b2b) !important;
}
#logout-button:hover {
background: linear-gradient(145deg, #a04040, #8c3a3a) !important;
}
/* Стили для выбора персонажа */
.character-selection {
margin-top: 15px;
margin-bottom: 15px;
padding: 15px;
background-color: rgba(0, 0, 0, 0.2);
border-radius: 6px;
border: 1px solid rgba(74, 80, 114, 0.5);
}
.character-selection h4 {
font-size: 1.1em;
color: var(--text-muted);
margin-bottom: 10px;
border: none;
padding: 0;
text-align: center;
}
.character-selection label {
display: inline-block;
margin: 0 15px;
cursor: pointer;
font-size: 1.05em;
padding: 5px 10px;
border-radius: 4px;
transition: background-color 0.2s ease, color 0.2s ease;
user-select: none; /* Не выделять текст при клике */
}
.character-selection input[type="radio"] {
display: none;
}
.character-selection input[type="radio"]:checked + label {
color: #fff;
font-weight: bold;
}
/* Стилизация для выбранных персонажей */
.character-selection input[type="radio"][value="elena"]:checked + label {
background-color: var(--accent-player);
box-shadow: 0 0 8px rgba(108, 149, 255, 0.5);
}
.character-selection input[type="radio"][value="almagest"]:checked + label {
background-color: var(--accent-almagest);
box-shadow: 0 0 8px rgba(199, 108, 255, 0.5);
}
.character-selection label:hover {
background-color: rgba(255, 255, 255, 0.1);
}
.character-selection label i {
margin-right: 8px;
vertical-align: middle;
}
/* Цвет иконок в выборе персонажа */
label[for="char-elena"] i {
color: var(--accent-player);
}
label[for="char-almagest"] i {
color: var(--accent-almagest);
}
/* --- Основная Структура Игры (.game-wrapper) --- */
.game-wrapper {
width: 100%;
height: 100%;
max-width: 1400px;
margin: 0 auto;
padding: 10px;
display: flex;
flex-direction: column;
gap: 10px;
overflow: hidden; /* Предотвращает выпадение контента */
}
.game-header {
flex-shrink: 0;
text-align: center;
padding: 5px 0 10px 0;
border-bottom: 1px solid var(--panel-border);
}
.game-header h1 {
font-size: 2em;
margin: 0;
text-shadow: 0 0 8px rgba(255, 255, 255, 0.5);
}
/* Стили для имен персонажей в заголовке */
.title-enchantress {
color: var(--accent-player);
}
/* Елена */
.title-knight {
color: var(--accent-opponent);
}
/* Балард */
.title-sorceress {
color: var(--accent-almagest);
}
/* Альмагест */
.separator i {
color: var(--text-light);
font-size: 0.8em;
margin: 0 15px;
}
.battle-arena-container {
flex-grow: 1;
display: flex;
gap: 10px;
overflow: hidden; /* Предотвращает выпадение контента */
}
.player-column,
.opponent-column {
flex: 1;
display: flex;
flex-direction: column;
gap: 10px;
min-width: 0; /* Для корректной работы flex с overflow */
overflow: hidden; /* Если контент внутри колонок может быть больше */
}
/* --- Стили Панелей Персонажей, Управления, Лога --- */
.fighter-panel,
.controls-panel-new,
.battle-log-new {
background: var(--panel-bg);
border: 1px solid var(--panel-border);
border-radius: 8px;
box-shadow: 0 0 15px rgba(0, 0, 0, 0.4), inset 0 0 10px rgba(0, 0, 0, 0.3);
padding: 15px;
display: flex;
flex-direction: column;
overflow: hidden; /* Контент внутри панелей не должен выходить за их пределы */
transition: box-shadow 0.3s ease, border-color 0.3s ease, opacity 0.3s ease-out, transform 0.3s ease-out;
}
/* Стили рамок панелей в зависимости от персонажа (для JS) */
.fighter-panel.panel-elena {
border-color: var(--accent-player);
}
.fighter-panel.panel-almagest {
border-color: var(--accent-almagest);
}
.fighter-panel.panel-balard {
border-color: var(--accent-opponent);
}
/* --- Панели Персонажей --- */
.panel-header {
flex-shrink: 0;
display: flex;
align-items: center;
gap: 10px;
padding-bottom: 10px;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
margin-bottom: 0; /* Убираем лишний отступ, если panel-content имеет свой margin-top */
}
.fighter-name {
font-size: 1.6em;
margin: 0;
flex-grow: 1;
text-align: left;
}
/* Цвета иконок в имени персонажа */
.fighter-name .icon-player {
color: var(--accent-player);
}
.fighter-name .icon-opponent {
color: var(--accent-opponent);
}
.fighter-name .icon-almagest {
color: var(--accent-almagest);
}
.character-visual {
flex-shrink: 0;
margin-bottom: 0;
}
.avatar-image {
display: block;
max-width: 50px; /* Фиксируем или делаем адаптивным */
height: auto; /* Для сохранения пропорций */
border-radius: 50%;
border: 2px solid var(--panel-border); /* Цвет рамки будет изменен JS или специфичным классом */
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.5);
}
/* Стили рамок аватаров (для JS) */
.avatar-image.avatar-elena {
border-color: var(--accent-player);
}
.avatar-image.avatar-almagest {
border-color: var(--accent-almagest);
}
.avatar-image.avatar-balard {
border-color: var(--accent-opponent);
}
.panel-content {
flex-grow: 1;
overflow-y: auto; /* Позволяет прокручивать контент, если он не помещается */
padding-right: 5px; /* Для отступа от скроллбара */
display: flex;
flex-direction: column;
gap: 10px;
min-height: 0; /* Для корректной работы flex с overflow */
padding-top: 10px; /* Отступ от panel-header */
margin-top: 0; /* Убрали margin-bottom у panel-header, добавили padding-top сюда */
}
.stat-bar-container {
display: flex;
align-items: center;
gap: 10px;
flex-shrink: 0;
}
.stat-bar-container .bar-icon {
flex-shrink: 0;
font-size: 1.4em;
}
/* Цвета иконок ресурсов (для JS) */
.stat-bar-container.health .bar-icon {
color: var(--hp-color);
}
.stat-bar-container.mana .bar-icon {
color: var(--mana-color);
}
.stat-bar-container.stamina .bar-icon {
color: var(--stamina-color);
}
.stat-bar-container.dark-energy .bar-icon {
color: var(--dark-energy-color);
}
.bar-wrapper {
flex-grow: 1;
}
.bar {
border-radius: 4px;
height: 20px;
border: 1px solid rgba(0, 0, 0, 0.5);
overflow: hidden;
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.5);
position: relative;
background-color: var(--bar-bg);
}
.bar-fill {
display: block;
height: 100%;
border-radius: 3px; /* чуть меньше, чем у родителя */
position: relative;
z-index: 2;
transition: width 0.4s ease-out;
}
.bar-text {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: 3;
display: flex;
justify-content: center;
align-items: center;
font-size: 0.75em;
font-weight: bold;
color: #fff;
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.9);
padding: 0 5px;
white-space: nowrap;
pointer-events: none; /* Чтобы текст не мешал кликам, если они есть */
}
/* Цвета Заливки Баров */
.health .bar-fill {
background-color: var(--hp-color);
}
.mana .bar-fill {
background-color: var(--mana-color);
}
.stamina .bar-fill {
background-color: var(--stamina-color);
}
.dark-energy .bar-fill {
background-color: var(--dark-energy-color);
}
/* Статус и Эффекты */
.status-area {
font-size: 0.9em;
display: flex;
align-items: baseline;
gap: 5px;
flex-shrink: 0;
min-height: 1.5em; /* Чтобы не прыгал layout */
}
.status-area .icon-status {
font-size: 1em;
flex-shrink: 0;
margin-top: 0.1em; /* Подгонка выравнивания */
}
.status-area strong {
color: var(--text-muted);
font-weight: normal;
flex-shrink: 0;
margin-right: 3px;
}
.status-area span {
font-weight: bold;
}
.status-area span.blocking {
color: var(--block-color);
font-style: italic;
}
.effects-area {
font-size: 0.9em;
display: flex;
flex-direction: column;
gap: 8px;
flex-shrink: 0;
min-height: 3em; /* Резервируем место */
}
.effect-category {
display: flex;
align-items: baseline;
gap: 5px;
}
.effect-category strong {
color: var(--text-muted);
font-weight: normal;
font-family: var(--font-main); /* Убедимся, что шрифт основной */
font-size: 0.9em;
flex-shrink: 0;
margin-right: 3px;
}
.effect-category .icon-effects-buff,
.effect-category .icon-effects-debuff {
font-size: 1em;
flex-shrink: 0;
margin-top: 0.1em; /* Подгонка выравнивания */
width: 1.2em;
text-align: center; /* Для иконок */
}
.effect-category .icon-effects-buff {
color: var(--heal-color);
}
.effect-category .icon-effects-debuff {
color: var(--damage-color);
}
.effect-list {
display: inline;
line-height: 1.4;
min-width: 0; /* Для переноса, если нужно */
font-weight: bold;
}
.effect {
display: inline-block;
margin: 2px 3px 2px 0;
padding: 1px 6px;
font-size: 0.8em;
border-radius: 10px;
border: 1px solid;
cursor: default;
font-weight: 600;
background-color: rgba(0, 0, 0, 0.2);
white-space: nowrap;
vertical-align: baseline;
}
/* Цвета рамок и текста для разных типов эффектов */
.effect-buff {
border-color: var(--heal-color);
color: var(--heal-color);
}
.effect-debuff {
border-color: var(--damage-color);
color: var(--damage-color);
}
.effect-stun {
border-color: var(--turn-color);
color: var(--turn-color);
}
/* Для безмолвия/стана */
.effect-block {
border-color: var(--block-color);
color: var(--block-color);
}
/* Для эффектов блока */
.effect-info {
border-color: var(--text-muted);
color: var(--text-muted);
}
/* --- Панель Управления --- */
.controls-panel-new {
flex-grow: 1;
min-height: 0;
display: flex;
flex-direction: column;
}
#turn-indicator {
flex-shrink: 0;
text-align: center;
font-size: 1.4em;
margin-bottom: 10px;
padding-bottom: 8px;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
transition: color 0.3s ease;
}
.controls-layout {
flex-grow: 1;
display: flex;
flex-direction: column;
gap: 10px;
overflow: hidden;
min-height: 0;
}
.control-group {
flex-shrink: 0;
}
.control-group h4 {
font-size: 0.9em;
color: var(--text-muted);
margin-bottom: 5px;
padding-bottom: 5px;
border-bottom: 1px dashed var(--panel-border);
text-transform: uppercase;
letter-spacing: 1px;
}
.basic-actions {
display: flex;
gap: 10px;
}
.action-button.basic {
flex: 1;
padding: 8px 5px;
font-size: 0.85em;
font-weight: bold;
background: var(--button-bg);
color: var(--button-text);
border: 1px solid rgba(0, 0, 0, 0.3);
border-radius: 5px;
cursor: pointer;
transition: all 0.15s ease;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4);
outline: none;
}
.action-button.basic:hover:enabled {
background: var(--button-hover-bg);
transform: translateY(-1px);
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.5);
}
.action-button.basic:active:enabled {
transform: translateY(0px);
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
}
/* Стиль для бафнутой атаки */
#button-attack.attack-buffed:enabled {
border: 2px solid var(--heal-color);
box-shadow: 0 0 10px 2px rgba(144, 238, 144, 0.6), 0 3px 6px rgba(0, 0, 0, 0.5);
background: linear-gradient(145deg, #70c070, #5a9a5a); /* Зеленый градиент */
transform: translateY(-1px); /* Небольшой подъем */
}
.ability-list {
flex-grow: 1;
display: flex;
flex-direction: column;
min-height: 0;
overflow: hidden;
}
.ability-list h4 {
flex-shrink: 0;
}
.abilities-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(75px, 1fr));
gap: 8px;
padding: 8px;
background-color: rgba(0, 0, 0, 0.2);
border-radius: 4px;
overflow-y: auto;
border: 1px solid rgba(0, 0, 0, 0.3);
flex-grow: 1;
position: relative; /* Для псевдоэлемента, если нужен */
}
.abilities-grid::after {
content: '';
display: block;
height: 10px;
width: 100%;
}
/* Отступ снизу для скролла */
.abilities-grid .placeholder-text {
grid-column: 1 / -1;
text-align: center;
color: var(--text-muted);
align-self: center;
font-size: 0.9em;
padding: 15px 0;
}
.ability-button {
aspect-ratio: 1 / 1;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 5px;
border-radius: 6px;
background: var(--button-ability-bg);
border: 1px solid var(--button-ability-border);
color: #fff;
text-align: center;
line-height: 1.15;
cursor: pointer;
transition: all 0.2s ease-out;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4);
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.6);
position: relative;
overflow: hidden;
outline: none;
}
.ability-button .ability-name {
font-size: 0.75em;
font-weight: bold;
margin-bottom: 2px;
display: block;
width: 95%;
}
.ability-button .ability-desc {
font-size: 0.65em;
font-weight: normal;
color: #aaccce;
opacity: 0.8;
text-shadow: none;
max-height: 2em;
overflow: hidden;
width: 95%;
display: block;
margin-top: auto; /* Прижимает описание вниз */
}
.ability-button:hover:enabled {
transform: scale(1.03) translateY(-1px);
background: var(--button-ability-hover-bg);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.5), 0 0 8px rgba(77, 176, 181, 0.4);
border-color: #77d9dd;
}
.ability-button:active:enabled {
transform: scale(1) translateY(0);
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3), 0 1px 2px rgba(0, 0, 0, 0.3);
filter: brightness(0.9);
}
/* --- Стили для отключенных кнопок и их состояний --- */
/* Базовый стиль для любой отключенной кнопки */
.ability-button:disabled,
.action-button.basic:disabled {
background: var(--button-disabled-bg) !important;
border-color: transparent !important;
color: var(--button-disabled-text) !important;
cursor: not-allowed !important;
transform: none !important;
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.4) !important;
opacity: 0.7;
text-shadow: none !important;
filter: grayscale(50%);
}
/* Стиль для индикации нехватки ресурса (красная пунктирная рамка) */
/* Применяется, когда кнопка имеет класс 'not-enough-resource', независимо от disabled */
.ability-button.not-enough-resource {
border: 2px dashed var(--damage-color); /* Красная пунктирная рамка */
animation: pulse-red-border 1s infinite ease-in-out; /* Пульсация */
}
/* Сочетание стиля нехватки ресурса и стандартного стиля disabled */
/* Сохраняет красную рамку поверх стандартного серого фона disabled */
.ability-button.not-enough-resource:disabled {
border-color: var(--damage-color); /* Гарантируем красную рамку */
/* Можно переопределить тень, если нужно специфичное сочетание */
box-shadow: inset 0 0 8px rgba(255, 80, 80, 0.2), 0 3px 6px rgba(0, 0, 0, 0.2), inset 0 1px 3px rgba(0, 0, 0, 0.4);
/* Опасити и фон наследуются от общего :disabled */
/* Анимация наследуется от .not-enough-resource */
}
/* Стиль для активного баффа (если кнопка баффа уже активна) */
/* Применяется, когда кнопка имеет класс 'buff-is-active', независимо от disabled */
.ability-button.buff-is-active {
/* Например, зеленая рамка или свечение */
border: 2px solid var(--heal-color);
box-shadow: 0 0 8px rgba(144, 238, 144, 0.5);
}
/* Сочетание активного баффа и стандартного стиля disabled */
.ability-button.buff-is-active:disabled {
border-color: var(--heal-color);
/* Опасити, фон, фильтр наследуются от :disabled */
}
/* Стиль для кнопок на КД или под безмолвием */
.ability-button.is-on-cooldown,
.ability-button.is-silenced {
filter: grayscale(70%) brightness(0.8); /* Затемнение и обесцвечивание */
}
/* Сочетание КД/безмолвия и стандартного стиля disabled */
.ability-button.is-on-cooldown:disabled,
.ability-button.is-silenced:disabled {
/* Убеждаемся, что фильтр остается */
filter: grayscale(70%) brightness(0.7); /* Чуть темнее в disabled состоянии */
/* Опасити и фон наследуются от :disabled */
}
/* Скрываем описание иконки на КД/безмолвии, чтобы освободить место для таймера/иконки */
.ability-button.is-on-cooldown .ability-name,
.ability-button.is-silenced .ability-name,
.ability-button.is-on-cooldown .ability-desc,
.ability-button.is-silenced .ability-desc {
opacity: 0.6; /* Приглушаем текст */
}
.ability-button.is-on-cooldown .ability-desc,
.ability-button.is-silenced .ability-desc {
display: none;
}
/* Стили для отображения кулдауна или безмолвия */
.ability-cooldown-display {
position: absolute;
bottom: 5px;
left: 0;
width: 100%;
text-align: center;
font-size: 0.75em;
font-weight: bold;
color: var(--turn-color);
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.7);
pointer-events: none; /* Чтобы текст не мешал кликам */
display: none; /* Изначально скрыт */
line-height: 1;
}
/* Показываем отображение кулдауна/безмолвия только когда кнопка в соответствующем состоянии */
.ability-button.is-on-cooldown .ability-cooldown-display,
.ability-button.is-silenced .ability-cooldown-display {
display: block !important; /* !important для переопределения display:none */
}
/* --- Панель Лога --- */
.battle-log-new {
height: var(--log-panel-fixed-height);
flex-shrink: 0;
display: flex;
flex-direction: column;
overflow: hidden;
}
.battle-log-new h3 {
flex-shrink: 0;
font-size: 1.4em;
margin-bottom: 10px;
text-align: center;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
padding-bottom: 8px;
}
#log-list {
list-style: none;
flex-grow: 1;
overflow-y: auto;
background-color: var(--log-bg);
border: 1px solid var(--log-border);
font-size: 0.85em;
border-radius: 6px;
color: var(--log-text);
padding: 10px;
min-height: 0; /* Для корректной работы flex-grow и overflow */
word-wrap: break-word; /* Перенос длинных слов */
}
#log-list li {
padding: 4px 8px;
border-bottom: 1px solid rgba(74, 80, 114, 0.5); /* Полупрозрачная граница */
line-height: 1.35;
transition: background-color 0.3s;
}
#log-list li:last-child {
border-bottom: none;
}
#log-list li:hover {
background-color: rgba(255, 255, 255, 0.03); /* Легкая подсветка при наведении */
}
/* Стили для типов логов (классы добавляются JS) */
.log-damage {
color: var(--damage-color);
font-weight: 500;
}
.log-heal {
color: var(--heal-color);
font-weight: 500;
}
.log-block {
color: var(--block-color);
font-style: italic;
}
.log-info {
color: #b0c4de;
}
/* Светло-голубой для общей информации */
.log-turn {
font-weight: bold;
color: var(--turn-color);
margin-top: 6px;
border-top: 1px solid rgba(255, 215, 0, 0.3);
padding-top: 6px;
font-size: 1.05em;
display: block; /* Чтобы занимал всю строку */
}
.log-system {
font-weight: bold;
color: var(--system-color);
font-style: italic;
opacity: 0.8;
}
.log-effect {
font-style: italic;
color: var(--effect-color);
}
/* --- Экран Конца Игры (Модальное Окно) --- */
.modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: var(--modal-bg);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
backdrop-filter: blur(4px) brightness(0.7);
opacity: 0;
pointer-events: none;
transition: opacity 0.4s ease-out;
}
/* Класс для скрытия модалки (добавляется JS) */
.modal.hidden {
display: none !important;
}
/* Состояние видимости модалки */
.modal:not(.hidden) {
opacity: 1;
pointer-events: auto;
}
.modal-content {
background: var(--modal-content-bg);
padding: 40px 50px;
border-radius: 10px;
text-align: center;
border: 1px solid var(--panel-border);
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.6);
color: var(--text-light);
/* Начальное состояние для анимации появления */
transform: scale(0.8) translateY(30px);
opacity: 0;
/* Анимация появления контента */
transition: transform 0.4s cubic-bezier(0.2, 0.9, 0.3, 1.2), opacity 0.4s ease-out;
}
/* Конечное состояние для анимации появления контента модалки */
.modal:not(.hidden) .modal-content {
transform: scale(1) translateY(0);
opacity: 1;
}
.modal-content h2#result-message {
margin-bottom: 25px;
font-family: var(--font-fancy);
font-size: 2.5em;
line-height: 1.2;
}
/* Стили для кнопки "В меню выбора игры" */
.modal-action-button {
padding: 12px 30px;
font-size: 1.1em;
cursor: pointer;
background: var(--button-bg);
color: var(--button-text);
border: 1px solid rgba(0, 0, 0, 0.3);
border-radius: 6px;
margin-top: 20px;
font-weight: bold;
text-transform: uppercase;
letter-spacing: 1px;
transition: all 0.2s ease;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.4);
outline: none;
}
.modal-action-button:hover:enabled {
background: var(--button-hover-bg);
transform: scale(1.05) translateY(-1px);
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.5);
}
.modal-action-button:active:enabled {
transform: scale(1) translateY(0);
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.4);
}
.modal-action-button:disabled {
background: var(--button-disabled-bg);
color: var(--button-disabled-text);
cursor: not-allowed;
opacity: 0.7;
}
.modal-action-button i {
margin-right: 8px;
}
/* --- Анимации --- */
/* Анимация пульсации красной рамки (для нехватки ресурса) */
@keyframes pulse-red-border {
0%, 100% {
border-color: var(--damage-color);
}
50% {
border-color: #ffb3b3;
}
}
/* Анимация вспышки при касте (добавляется JS классом) */
@keyframes flash-effect {
0%, 100% {
/* Возвращаем к исходным стилям панели */
box-shadow: var(--initial-box-shadow, 0 0 15px rgba(0, 0, 0, 0.4), inset 0 0 10px rgba(0, 0, 0, 0.3));
border-color: var(--initial-border-color, var(--panel-border));
transform: scale(1);
}
50% {
/* Стиль вспышки */
box-shadow: 0 0 25px 10px var(--flash-color-outer, rgba(255, 255, 255, 0.7)),
inset 0 0 15px var(--flash-color-inner, rgba(255, 255, 255, 0.4)),
0 0 15px rgba(0, 0, 0, 0.4); /* Сохраняем базовую тень */
border-color: var(--flash-border-color, #ffffff);
transform: scale(1.005); /* Легкое увеличение */
}
}
/* Применение анимации каста к панели (добавляется через JS) */
/* Пример: #player-panel.is-casting-heal */
[class*="is-casting-"] {
animation: flash-effect var(--cast-duration) ease-out;
/* Сохраняем исходные значения для возврата в keyframes */
/* JS должен будет установить --initial-box-shadow и --initial-border-color */
/* Или, определяем их здесь для известных панелей */
}
/* Цвета для разных кастов (переменные для keyframes flash-effect) */
#player-panel.is-casting-heal, #opponent-panel.is-casting-heal {
--flash-color-outer: rgba(144, 238, 144, 0.7);
--flash-color-inner: rgba(144, 238, 144, 0.4);
--flash-border-color: var(--heal-color);
--initial-border-color: var(--accent-player); /* Для панели игрока Елена */
}
#player-panel.is-casting-fireball, #opponent-panel.is-casting-fireball {
--flash-color-outer: rgba(255, 100, 100, 0.7);
--flash-color-inner: rgba(255, 100, 100, 0.4);
--flash-border-color: var(--damage-color);
--initial-border-color: var(--accent-player); /* Для панели игрока Елена */
}
/* Пример для Альмагест */
#player-panel.is-casting-shadowBolt, #opponent-panel.is-casting-shadowBolt {
--flash-color-outer: rgba(138, 43, 226, 0.6);
--flash-color-inner: rgba(138, 43, 226, 0.3);
--flash-border-color: var(--dark-energy-color);
--initial-border-color: var(--accent-almagest); /* Для панели игрока Альмагест */
}
/* Пример для Баларда (если он когда-либо будет кастовать с анимацией) */
#opponent-panel.is-casting-darkPatronage {
--flash-color-outer: rgba(100, 100, 100, 0.7);
--flash-color-inner: rgba(100, 100, 100, 0.4);
--flash-border-color: #888;
--initial-border-color: var(--accent-opponent); /* Для панели оппонента Балард */
}
/* Добавить для других способностей и персонажей */
/* Анимация тряски при получении урона */
@keyframes shake-opponent {
0%, 100% {
transform: translateX(0);
}
10%, 30%, 50%, 70%, 90% {
transform: translateX(-4px) rotate(-0.5deg);
}
20%, 40%, 60%, 80% {
transform: translateX(4px) rotate(0.5deg);
}
}
/* Применение анимации тряски к панели противника (добавляется JS классом) */
#opponent-panel.is-shaking {
animation: shake-opponent var(--shake-duration) cubic-bezier(.36, .07, .19, .97) both;
/* Дополнительные свойства для лучшей производительности анимации */
transform: translate3d(0, 0, 0);
backface-visibility: hidden;
perspective: 1000px;
}
/* Анимация растворения панели противника (добавляется JS классом) */
#opponent-panel.dissolving {
/* Начальные стили перед анимацией задаются JS, конечные - здесь */
opacity: 0;
transform: scale(0.9) translateY(20px);
/* Длительность анимации берется из переменной */
transition: opacity var(--dissolve-duration) ease-in, transform var(--dissolve-duration) ease-in;
pointer-events: none; /* Нельзя взаимодействовать во время исчезновения */
}
/* Состояние после завершения анимации dissolving, если класс остается */
/* #opponent-panel.dissolved-state { opacity: 0; transform: scale(0.9) translateY(20px); } */
/* Анимация короткой тряски (например, при промахе?) */
@keyframes shake-short {
0%, 100% {
transform: translateX(0);
}
25% {
transform: translateX(-3px);
}
50% {
transform: translateX(3px);
}
75% {
transform: translateX(-3px);
}
}
.shake-short {
animation: shake-short 0.3s ease-in-out;
}
/* --- Отзывчивость (Медиа-запросы) --- */
@media (max-width: 900px) {
body {
height: auto; /* Позволяем body расти по контенту */
overflow-y: auto; /* Включаем прокрутку для body, если нужно */
padding: 5px 0; /* Уменьшаем отступы */
font-size: 15px;
justify-content: flex-start; /* Чтобы контент не пытался всегда быть по центру */
}
.auth-game-setup-wrapper {
max-height: none; /* Убираем ограничение по высоте, body будет скроллиться */
}
.game-wrapper {
padding: 5px;
gap: 5px;
height: auto;
}
.game-header h1 {
font-size: 1.5em;
}
.battle-arena-container {
flex-direction: column;
height: auto;
overflow: visible;
}
.player-column,
.opponent-column {
width: 100%;
height: auto;
overflow: visible;
}
.fighter-panel,
.controls-panel-new,
.battle-log-new {
min-height: auto; /* Убираем min-height, пусть контент определяет */
height: auto; /* Высота по контенту */
padding: 10px;
flex-grow: 0; /* Панели не должны растягиваться */
flex-shrink: 1; /* Но могут сжиматься, если нужно */
}
.controls-panel-new {
min-height: 200px;
}
/* Сохраняем для удобства клика */
.battle-log-new {
height: auto;
min-height: 150px;
}
/* Лог тоже по контенту */
#log-list {
max-height: 200px;
}
/* Ограничиваем высоту списка логов */
.abilities-grid {
max-height: none;
overflow-y: visible;
padding-bottom: 8px;
}
.abilities-grid::after {
display: none;
}
/* Убираем псевдоэлемент, т.к. нет скролла */
.ability-list,
.controls-layout {
overflow: visible;
}
.fighter-name {
font-size: 1.3em;
}
.panel-content {
margin-top: 10px;
}
/* Восстанавливаем отступ, если был убран */
.stat-bar-container .bar-icon {
font-size: 1.2em;
}
.bar {
height: 18px;
}
.effects-area,
.effect {
font-size: 0.85em;
}
#turn-indicator {
font-size: 1.2em;
margin-bottom: 10px;
}
.action-button.basic {
font-size: 0.8em;
padding: 8px 4px;
}
.abilities-grid {
grid-template-columns: repeat(auto-fit, minmax(80px, 1fr));
gap: 8px;
padding: 8px;
}
.ability-button {
font-size: 0.75em;
padding: 5px;
}
.ability-button .ability-name {
margin-bottom: 2px;
}
.ability-button .ability-desc {
font-size: 0.65em;
}
.modal-content {
padding: 25px 30px;
width: 90%;
max-width: 400px;
}
.modal-content h2#result-message {
font-size: 1.8em;
}
.modal-action-button {
font-size: 1em;
padding: 10px 20px;
}
/* Адаптируем кнопку в модалке */
/* Стили для auth-game-setup на планшетах */
#game-setup {
max-width: 95%;
padding: 15px;
}
#game-setup h2 {
font-size: 1.6em;
}
#game-setup h3 {
font-size: 1.1em;
}
#game-setup button {
padding: 8px 12px;
font-size: 0.9em;
}
#game-setup input[type="text"] {
width: calc(100% - 90px);
max-width: 200px;
padding: 8px;
}
#available-games-list {
max-height: 180px;
}
.character-selection label {
margin: 0 10px;
font-size: 1em;
}
}
@media (max-width: 480px) {
body {
font-size: 14px;
}
.game-header h1 {
font-size: 1.3em;
}
.fighter-name {
font-size: 1.2em;
}
.abilities-grid {
grid-template-columns: repeat(auto-fit, minmax(65px, 1fr));
gap: 5px;
padding: 5px;
}
.ability-button {
font-size: 0.7em;
padding: 4px;
}
.ability-button .ability-name {
margin-bottom: 1px;
}
.ability-button .ability-desc {
display: none;
}
/* Скрываем описание на маленьких экранах */
#log-list {
font-size: 0.8em;
max-height: 150px;
}
.modal-content {
padding: 20px;
}
.modal-content h2#result-message {
font-size: 1.6em;
}
.modal-action-button {
font-size: 0.9em;
padding: 8px 16px;
}
/* Адаптируем кнопку в модалке */
/* Стили для auth-game-setup на мобильных */
.auth-game-setup-wrapper {
padding: 15px;
}
#game-setup {
padding: 10px;
}
#game-setup h2 {
font-size: 1.4em;
}
#game-setup button {
padding: 7px 10px;
font-size: 0.85em;
margin: 5px;
}
#game-setup input[type="text"],
#game-setup button {
/* Делаем кнопки и инпуты в game-setup блочными для лучшего отображения на мобильных */
display: block;
width: 100%;
margin-left: 0;
margin-right: 0;
}
#game-setup input[type="text"] {
max-width: none;
margin-bottom: 10px;
}
#game-setup div>input[type="text"]+button {
margin-top: 5px;
}
/* Отступ для кнопки после инпута */
#available-games-list {
max-height: 120px;
}
#available-games-list li button {
font-size: 0.75em;
padding: 5px 8px;
}
.character-selection {
padding: 10px;
}
.character-selection label {
margin: 0 5px 5px 5px;
font-size: 0.9em;
display: block;
}
/* Лейблы в столбик */
.character-selection label i {
margin-right: 5px;
}
}