Files
website-collection/chess/public/styles.css
T

1488 lines
24 KiB
CSS
Raw Normal View History

2026-08-22 17:35:26 +00:00
/* =========================================================
CHESS APP — COMPLETE STYLES
Исправленная версия:
- шахматная доска не съезжает
- адаптивность PC / планшет / телефон
- Party Mode
- чат
- часы
- кнопки сдачи / ничьей / реванша
========================================================= */
:root {
--bg: #0e0f13;
--bg-2: #15171d;
--panel: rgba(25, 27, 34, 0.94);
--panel-2: rgba(31, 34, 42, 0.96);
--border: rgba(255, 255, 255, 0.09);
--border-hover: rgba(255, 255, 255, 0.18);
--text: #f1f1f1;
--text-soft: #a7abb5;
--text-muted: #727782;
--accent: #d9a441;
--accent-hover: #edbb58;
--danger: #d95c5c;
--success: #65b97c;
--warning: #d7a84b;
--board-light: #e6d3ad;
--board-dark: #9b754c;
--board-size: min(78vh, 720px);
--radius: 12px;
--shadow:
0 18px 50px rgba(0, 0, 0, 0.35);
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html {
width: 100%;
min-height: 100%;
background: var(--bg);
color: var(--text);
font-family:
Inter,
system-ui,
-apple-system,
BlinkMacSystemFont,
"Segoe UI",
sans-serif;
}
body {
width: 100%;
min-height: 100vh;
min-height: 100dvh;
background:
radial-gradient(
circle at top left,
rgba(217, 164, 65, 0.055),
transparent 32%
),
linear-gradient(
145deg,
#0b0c10,
#111319 55%,
#0b0c10
);
color: var(--text);
overflow-x: hidden;
}
button,
input,
textarea {
font: inherit;
}
button {
border: 0;
outline: 0;
}
button:focus-visible,
input:focus-visible,
textarea:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
}
.hidden {
display: none !important;
}
/* =========================================================
APP
========================================================= */
#app {
width: 100%;
min-height: 100vh;
min-height: 100dvh;
display: flex;
flex-direction: column;
}
/* =========================================================
HEADER
========================================================= */
.topbar,
header {
width: 100%;
min-height: 64px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 18px;
background: rgba(16, 17, 22, 0.92);
border-bottom: 1px solid var(--border);
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
position: sticky;
top: 0;
z-index: 100;
}
.logo {
display: flex;
align-items: center;
gap: 10px;
color: var(--text);
font-size: 19px;
font-weight: 700;
letter-spacing: 0.4px;
}
.logo span {
color: var(--accent);
}
.header-actions {
display: flex;
align-items: center;
gap: 8px;
}
/* =========================================================
BUTTONS
========================================================= */
.btn {
min-height: 40px;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 7px;
padding: 8px 14px;
border: 1px solid var(--border);
border-radius: 8px;
background: rgba(255, 255, 255, 0.045);
color: var(--text);
cursor: pointer;
transition:
background 0.18s ease,
border-color 0.18s ease,
transform 0.15s ease,
color 0.18s ease;
}
.btn:hover {
background: rgba(255, 255, 255, 0.085);
border-color: var(--border-hover);
}
.btn:active {
transform: translateY(1px);
}
.btn-primary {
background: var(--accent);
border-color: var(--accent);
color: #17120a;
font-weight: 700;
}
.btn-primary:hover {
background: var(--accent-hover);
border-color: var(--accent-hover);
}
.btn-danger {
color: #fff;
background: rgba(217, 92, 92, 0.13);
border-color: rgba(217, 92, 92, 0.3);
}
.btn-danger:hover {
background: rgba(217, 92, 92, 0.22);
}
.btn-success {
color: #fff;
background: rgba(101, 185, 124, 0.13);
border-color: rgba(101, 185, 124, 0.3);
}
.btn-success:hover {
background: rgba(101, 185, 124, 0.22);
}
.btn-warning {
color: #fff;
background: rgba(215, 168, 75, 0.13);
border-color: rgba(215, 168, 75, 0.3);
}
/* =========================================================
MAIN LAYOUT
========================================================= */
.main,
main {
width: 100%;
flex: 1;
display: grid;
grid-template-columns:
minmax(0, 1fr)
minmax(260px, 350px);
gap: 18px;
padding: 18px;
align-items: start;
}
/* =========================================================
GAME AREA
========================================================= */
.game-area {
min-width: 0;
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
}
/* =========================================================
PLAYER
========================================================= */
.player {
width: min(var(--board-size), 100%);
display: flex;
align-items: center;
justify-content: space-between;
min-height: 48px;
margin: 0 auto 8px;
padding: 7px 10px;
background: rgba(255, 255, 255, 0.035);
border: 1px solid var(--border);
border-radius: 9px;
}
.player-info {
min-width: 0;
display: flex;
align-items: center;
gap: 9px;
}
.player-avatar {
width: 32px;
height: 32px;
flex: 0 0 32px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
background: rgba(255, 255, 255, 0.08);
}
.player-name {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-weight: 600;
}
.player-status {
color: var(--text-muted);
font-size: 12px;
}
/* =========================================================
CHESS CLOCK
========================================================= */
.clock {
min-width: 82px;
padding: 7px 10px;
border-radius: 7px;
background: #0a0b0e;
border: 1px solid rgba(255, 255, 255, 0.07);
color: #fff;
text-align: center;
font-family:
"SFMono-Regular",
Consolas,
"Liberation Mono",
monospace;
font-size: 19px;
font-weight: 700;
letter-spacing: 1px;
}
.clock.active {
background: rgba(217, 164, 65, 0.14);
border-color: rgba(217, 164, 65, 0.45);
color: var(--accent);
}
.clock.low {
color: var(--danger);
border-color: rgba(217, 92, 92, 0.4);
}
/* =========================================================
BOARD WRAPPER
========================================================= */
.board-wrapper {
width: min(var(--board-size), calc(100vw - 36px));
aspect-ratio: 1 / 1;
position: relative;
flex: 0 0 auto;
margin: 0 auto;
border-radius: 4px;
box-shadow:
0 15px 40px rgba(0, 0, 0, 0.38),
0 0 0 1px rgba(255, 255, 255, 0.07);
overflow: hidden;
}
/*
ВАЖНО:
Доска всегда квадратная.
Не использовать width: 100% без aspect-ratio.
*/
#board,
.chessboard,
.board {
width: 100% !important;
height: 100% !important;
aspect-ratio: 1 / 1;
display: grid !important;
grid-template-columns:
repeat(8, minmax(0, 1fr)) !important;
grid-template-rows:
repeat(8, minmax(0, 1fr)) !important;
position: relative;
overflow: hidden;
}
/* =========================================================
CHESS SQUARE
========================================================= */
.square,
.cell,
.board-square {
width: 100%;
height: 100%;
min-width: 0;
min-height: 0;
position: relative;
display: flex;
align-items: center;
justify-content: center;
user-select: none;
-webkit-user-select: none;
touch-action: manipulation;
cursor: pointer;
}
.square.light,
.cell.light,
.board-square.light {
background: var(--board-light);
}
.square.dark,
.cell.dark,
.board-square.dark {
background: var(--board-dark);
}
.square:hover {
filter: brightness(1.05);
}
/* =========================================================
CHESS PIECES
========================================================= */
.piece {
width: 90%;
height: 90%;
display: flex;
align-items: center;
justify-content: center;
position: relative;
z-index: 4;
font-family:
"Noto Sans Symbols 2",
"Segoe UI Symbol",
"DejaVu Sans",
sans-serif;
font-size: clamp(
28px,
calc(var(--board-size) / 10),
72px
);
line-height: 1;
cursor: pointer;
user-select: none;
-webkit-user-select: none;
transition:
transform 0.1s ease;
}
.square:active .piece {
transform: scale(0.95);
}
/* белые фигуры */
.piece.white,
.piece[data-color="w"] {
color: #fff;
text-shadow:
0 1px 0 #777,
0 2px 2px rgba(0, 0, 0, 0.5);
}
/* чёрные фигуры */
.piece.black,
.piece[data-color="b"] {
color: #171717;
text-shadow:
0 1px 0 rgba(255,255,255,0.15),
0 2px 2px rgba(0, 0, 0, 0.35);
}
/* =========================================================
SELECTED SQUARE
========================================================= */
.square.selected {
box-shadow:
inset 0 0 0 4px rgba(217, 164, 65, 0.85);
}
.square.last-move {
box-shadow:
inset 0 0 0 999px rgba(217, 164, 65, 0.16);
}
.square.legal::after {
content: "";
width: 23%;
height: 23%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border-radius: 50%;
background: rgba(25, 25, 25, 0.28);
pointer-events: none;
}
.square.capture::after {
content: "";
position: absolute;
inset: 8%;
border-radius: 50%;
border: 4px solid rgba(217, 164, 65, 0.75);
pointer-events: none;
}
/* =========================================================
CHECK
========================================================= */
.square.check {
background:
radial-gradient(
circle,
rgba(217, 70, 70, 0.9),
rgba(180, 40, 40, 0.5) 50%,
transparent 75%
);
}
/* =========================================================
BOARD COORDINATES
========================================================= */
.coordinate {
position: absolute;
z-index: 8;
font-size: clamp(8px, 1.2vw, 13px);
font-weight: 700;
pointer-events: none;
opacity: 0.7;
}
.coordinate.rank {
top: 3px;
left: 4px;
}
.coordinate.file {
right: 4px;
bottom: 2px;
}
/* =========================================================
GAME CONTROLS
========================================================= */
.game-controls {
width: min(var(--board-size), 100%);
display: grid;
grid-template-columns:
repeat(4, minmax(0, 1fr));
gap: 8px;
margin-top: 12px;
}
.game-controls .btn {
width: 100%;
}
/* =========================================================
SIDEBAR
========================================================= */
.sidebar {
width: 100%;
min-width: 0;
display: flex;
flex-direction: column;
gap: 12px;
}
.panel {
width: 100%;
background: var(--panel);
border: 1px solid var(--border);
border-radius: var(--radius);
box-shadow: var(--shadow);
overflow: hidden;
}
.panel-header {
min-height: 48px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 13px;
border-bottom: 1px solid var(--border);
font-weight: 700;
}
.panel-title {
font-size: 14px;
}
.panel-content {
padding: 12px;
}
/* =========================================================
GAME INFO
========================================================= */
.game-info {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 8px;
}
.info-item {
padding: 10px;
background: rgba(255, 255, 255, 0.035);
border: 1px solid var(--border);
border-radius: 8px;
}
.info-label {
color: var(--text-muted);
font-size: 11px;
}
.info-value {
margin-top: 3px;
font-weight: 700;
}
/* =========================================================
PARTY MODE
========================================================= */
.party {
width: 100%;
}
.party-users {
display: flex;
flex-direction: column;
gap: 7px;
max-height: 250px;
overflow-y: auto;
}
.party-user {
min-height: 40px;
display: flex;
align-items: center;
gap: 9px;
padding: 7px 9px;
background: rgba(255, 255, 255, 0.035);
border: 1px solid var(--border);
border-radius: 8px;
}
.party-user-avatar {
width: 28px;
height: 28px;
flex: 0 0 28px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
background: rgba(255, 255, 255, 0.08);
}
.party-user-name {
min-width: 0;
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.party-user-status {
width: 8px;
height: 8px;
border-radius: 50%;
background: var(--success);
}
/* =========================================================
SPECTATORS
========================================================= */
.spectators {
color: var(--text-soft);
font-size: 13px;
}
.spectators strong {
color: var(--text);
}
/* =========================================================
CHAT
========================================================= */
.chat {
display: flex;
flex-direction: column;
height: 380px;
min-height: 280px;
}
.chat-messages {
flex: 1;
min-height: 0;
overflow-y: auto;
display: flex;
flex-direction: column;
gap: 7px;
padding: 10px;
}
.chat-message {
max-width: 88%;
padding: 7px 9px;
background: rgba(255, 255, 255, 0.05);
border: 1px solid var(--border);
border-radius: 8px;
font-size: 13px;
overflow-wrap: anywhere;
}
.chat-message.own {
align-self: flex-end;
background: rgba(217, 164, 65, 0.12);
border-color: rgba(217, 164, 65, 0.25);
}
.chat-author {
margin-bottom: 2px;
color: var(--accent);
font-size: 11px;
font-weight: 700;
}
.chat-input-area {
display: flex;
gap: 7px;
padding: 9px;
border-top: 1px solid var(--border);
}
.chat-input {
min-width: 0;
flex: 1;
height: 40px;
padding: 0 10px;
border: 1px solid var(--border);
border-radius: 8px;
background: rgba(0, 0, 0, 0.2);
color: var(--text);
outline: none;
}
.chat-input::placeholder {
color: var(--text-muted);
}
.chat-input:focus {
border-color: rgba(217, 164, 65, 0.5);
}
.chat-send {
width: 40px;
height: 40px;
flex: 0 0 40px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 8px;
background: var(--accent);
color: #17120a;
cursor: pointer;
}
/* =========================================================
MODAL
========================================================= */
.modal {
position: fixed;
inset: 0;
z-index: 1000;
display: flex;
align-items: center;
justify-content: center;
padding: 18px;
background: rgba(0, 0, 0, 0.68);
backdrop-filter: blur(7px);
-webkit-backdrop-filter: blur(7px);
}
.modal.hidden {
display: none !important;
}
.modal-content {
width: min(500px, 100%);
max-height: calc(100vh - 36px);
max-height: calc(100dvh - 36px);
overflow-y: auto;
padding: 20px;
background: var(--panel-2);
border: 1px solid var(--border);
border-radius: 12px;
box-shadow:
0 30px 80px rgba(0, 0, 0, 0.55);
}
.modal-title {
margin-bottom: 14px;
font-size: 20px;
font-weight: 700;
}
.modal-actions {
display: flex;
justify-content: flex-end;
gap: 8px;
margin-top: 18px;
}
/* =========================================================
GAME RESULT
========================================================= */
.game-result {
position: absolute;
inset: 0;
z-index: 50;
display: flex;
align-items: center;
justify-content: center;
background: rgba(0, 0, 0, 0.58);
backdrop-filter: blur(3px);
}
.game-result-card {
width: min(350px, calc(100% - 30px));
padding: 22px;
text-align: center;
background: rgba(20, 21, 26, 0.96);
border: 1px solid var(--border);
border-radius: 12px;
box-shadow: var(--shadow);
}
.game-result-title {
font-size: 24px;
font-weight: 800;
}
.game-result-text {
margin-top: 7px;
color: var(--text-soft);
}
.game-result-actions {
display: flex;
gap: 8px;
margin-top: 18px;
}
.game-result-actions .btn {
flex: 1;
}
/* =========================================================
NOTIFICATIONS
========================================================= */
.toast-container {
position: fixed;
right: 16px;
bottom: 16px;
z-index: 2000;
display: flex;
flex-direction: column;
gap: 8px;
width: min(350px, calc(100vw - 32px));
}
.toast {
padding: 11px 13px;
background: rgba(27, 29, 36, 0.96);
border: 1px solid var(--border);
border-radius: 9px;
box-shadow: var(--shadow);
font-size: 13px;
}
/* =========================================================
SCROLLBARS
========================================================= */
* {
scrollbar-width: thin;
scrollbar-color: rgba(255,255,255,0.15) transparent;
}
::-webkit-scrollbar {
width: 7px;
height: 7px;
}
::-webkit-scrollbar-track {
background: transparent;
}
::-webkit-scrollbar-thumb {
background: rgba(255,255,255,0.15);
border-radius: 10px;
}
::-webkit-scrollbar-thumb:hover {
background: rgba(255,255,255,0.25);
}
/* =========================================================
TABLET
========================================================= */
@media (max-width: 1100px) {
:root {
--board-size: min(72vw, 680px);
}
.main,
main {
grid-template-columns:
minmax(0, 1fr)
300px;
gap: 12px;
padding: 12px;
}
.game-controls {
grid-template-columns:
repeat(2, minmax(0, 1fr));
}
}
/* =========================================================
SMALL TABLET / LARGE PHONE
========================================================= */
@media (max-width: 820px) {
:root {
--board-size: min(
calc(100vw - 24px),
680px
);
}
.main,
main {
display: flex;
flex-direction: column;
width: 100%;
padding: 10px;
}
.game-area {
width: 100%;
}
.sidebar {
width: 100%;
display: grid;
grid-template-columns:
repeat(2, minmax(0, 1fr));
align-items: start;
}
.sidebar .chat {
grid-column: 1 / -1;
}
.board-wrapper {
width: min(
calc(100vw - 20px),
680px
);
}
.game-controls {
width: min(
calc(100vw - 20px),
680px
);
}
}
/* =========================================================
PHONE
========================================================= */
@media (max-width: 600px) {
:root {
--board-size: calc(100vw - 16px);
}
body {
overflow-x: hidden;
}
.topbar,
header {
min-height: 54px;
padding:
8px 9px;
position: relative;
}
.logo {
font-size: 16px;
}
.header-actions {
gap: 5px;
}
.header-actions .btn {
min-height: 36px;
padding: 6px 9px;
font-size: 12px;
}
.main,
main {
width: 100%;
padding: 8px;
gap: 10px;
}
.board-wrapper {
width: calc(100vw - 16px);
max-width: none;
border-radius: 2px;
}
#board,
.chessboard,
.board {
width: 100% !important;
height: 100% !important;
}
.piece {
width: 94%;
height: 94%;
font-size: calc(
(100vw - 16px) / 10
);
}
.player {
width: calc(100vw - 16px);
min-height: 43px;
padding: 5px 7px;
margin-bottom: 6px;
}
.player-avatar {
width: 27px;
height: 27px;
flex-basis: 27px;
}
.player-name {
max-width: 150px;
font-size: 13px;
}
.player-status {
font-size: 10px;
}
.clock {
min-width: 68px;
padding: 5px 7px;
font-size: 15px;
}
.game-controls {
width: calc(100vw - 16px);
grid-template-columns:
repeat(2, minmax(0, 1fr));
gap: 6px;
margin-top: 8px;
}
.game-controls .btn {
min-height: 40px;
padding: 7px 8px;
font-size: 12px;
}
.sidebar {
display: flex;
width: 100%;
}
.panel {
border-radius: 9px;
}
.chat {
height: 330px;
}
.modal {
padding: 10px;
}
.modal-content {
padding: 16px;
border-radius: 10px;
}
.modal-actions {
flex-direction: column;
}
.modal-actions .btn {
width: 100%;
}
.game-result-actions {
flex-direction: column;
}
.game-result-actions .btn {
width: 100%;
}
}
/* =========================================================
VERY SMALL PHONES
========================================================= */
@media (max-width: 380px) {
.main,
main {
padding: 5px;
}
.board-wrapper,
.player,
.game-controls {
width: calc(100vw - 10px);
}
.piece {
font-size: calc(
(100vw - 10px) / 10
);
}
.clock {
min-width: 62px;
font-size: 14px;
}
.player-name {
max-width: 105px;
}
.game-controls .btn {
font-size: 11px;
padding: 6px;
}
}
/* =========================================================
LANDSCAPE PHONE
========================================================= */
@media (max-height: 600px) and (orientation: landscape) {
:root {
--board-size: min(
calc(100vh - 90px),
calc(100vw - 250px)
);
}
.topbar,
header {
min-height: 46px;
padding: 5px 10px;
}
.main,
main {
display: flex;
flex-direction: row;
align-items: flex-start;
padding: 8px;
}
.game-area {
flex: 1;
}
.sidebar {
width: 280px;
flex: 0 0 280px;
max-height: calc(100vh - 62px);
overflow-y: auto;
}
.board-wrapper {
width: var(--board-size);
}
.player,
.game-controls {
width: var(--board-size);
}
.chat {
height: 260px;
}
}
/* =========================================================
SAFE AREA — ANDROID / IOS
========================================================= */
@supports (padding: env(safe-area-inset-bottom)) {
.topbar,
header {
padding-top:
max(
8px,
env(safe-area-inset-top)
);
}
body {
padding-bottom:
env(safe-area-inset-bottom);
}
}
/* =========================================================
REDUCED MOTION
========================================================= */
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}