studio/src/editor/ToolboxModal.module.css
min 6b857636c3 fix(studio): крестик закрытия Toolbox прижат к правому краю шапки
После переработки header убрал .headerInfo (flex:1), который раздвигал
заголовок и крестик → крестик прилип к названию. Добавил margin-left:auto
кнопке закрытия.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 07:28:32 +03:00

604 lines
14 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.

.overlay {
position: fixed;
inset: 0;
background: rgba(7, 10, 20, 0.78);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
z-index: 1000;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
font-family: "Roboto Condensed", system-ui, -apple-system, sans-serif;
animation: tbOverlayFadeIn 0.18s ease;
}
@keyframes tbOverlayFadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.modal {
background: var(--bg-dark);
border: 1px solid var(--border);
border-radius: 22px;
width: min(1300px, 96vw);
height: min(820px, 92vh);
display: flex;
flex-direction: column;
box-shadow:
0 32px 80px rgba(0, 0, 0, 0.6),
0 0 0 1px rgba(79, 116, 255, 0.12);
overflow: hidden;
animation: tbSlideIn 0.28s cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes tbSlideIn {
from { opacity: 0; transform: translateY(20px) scale(0.96); }
to { opacity: 1; transform: translateY(0) scale(1); }
}
.header {
display: flex;
align-items: center;
gap: 14px;
padding: 22px 26px;
background: linear-gradient(135deg, var(--accent) 0%, var(--accent2) 100%);
color: #fff;
position: relative;
overflow: hidden;
}
.header::before {
content: '';
position: absolute;
top: -30px; right: 60px;
width: 90px; height: 90px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.10);
pointer-events: none;
}
.title {
margin: 0;
color: #fff;
font-size: 20px;
font-weight: 800;
letter-spacing: -0.3px;
position: relative;
z-index: 1;
}
.headerInfo {
flex: 1;
color: rgba(255, 255, 255, 0.78);
font-size: 13px;
font-weight: 600;
position: relative;
z-index: 1;
}
.closeBtn {
margin-left: auto; /* прижать крестик к правому краю шапки */
background: rgba(255, 255, 255, 0.16);
border: 1px solid rgba(255, 255, 255, 0.25);
border-radius: 10px;
color: #fff;
width: 36px;
height: 36px;
cursor: pointer;
font-size: 20px;
font-weight: 700;
transition: all 150ms ease;
position: relative;
z-index: 1;
font-family: inherit;
}
.closeBtn:hover {
background: rgba(255, 255, 255, 0.28);
transform: scale(1.05);
color: #fff;
}
/* === Поиск === */
.searchBar {
padding: 12px 18px;
background: var(--bg-darkest);
border-bottom: 1px solid var(--border);
}
.searchInput {
width: 100%;
padding: 11px 16px;
background: var(--bg-mid);
border: 1.5px solid var(--border);
border-radius: 10px;
color: var(--text);
font-size: 14px;
font-weight: 500;
outline: none;
transition: all 150ms ease;
font-family: inherit;
}
.searchInput:focus {
border-color: var(--accent);
box-shadow: 0 0 0 3px rgba(79, 116, 255, 0.22);
background: var(--bg-light);
}
.searchInput::placeholder {
color: var(--text-dim);
}
/* === Корневые разделы (Стандартные / Мои / Сообщество) === */
.sectionTabs {
display: flex;
gap: 4px;
padding: 10px 18px 0;
background: var(--bg-darkest);
border-bottom: 1px solid var(--border);
}
.sectionTab {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 10px 18px;
background: transparent;
border: none;
border-bottom: 3px solid transparent;
color: var(--text-dim);
font-size: 14px;
font-weight: 800;
cursor: pointer;
transition: all 180ms ease;
font-family: inherit;
letter-spacing: -0.2px;
}
.sectionTab:hover {
color: var(--accent-bright);
background: rgba(79, 116, 255, 0.10);
}
.sectionTabActive {
color: var(--accent-bright);
border-bottom-color: var(--accent-bright);
}
.sectionTabActive:hover {
background: rgba(79, 116, 255, 0.12);
}
/* === Категории === */
.categoryTabs {
display: flex;
flex-wrap: wrap;
gap: 6px;
padding: 10px 18px;
background: var(--bg-darkest);
border-bottom: 1px solid var(--border);
max-height: 100px;
overflow-y: auto;
}
.categoryTab {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 7px 14px;
background: var(--bg-mid);
border: 1px solid var(--border);
border-radius: 999px;
color: var(--text-dim);
font-size: 12px;
font-weight: 700;
cursor: pointer;
transition: all 200ms ease;
white-space: nowrap;
font-family: inherit;
}
.categoryTab:hover {
color: var(--accent-bright);
border-color: var(--accent);
background: rgba(79, 116, 255, 0.12);
}
.categoryTabActive {
background: linear-gradient(135deg, var(--accent) 0%, var(--accent2) 100%);
border-color: transparent;
color: #fff;
box-shadow: 0 4px 12px rgba(79, 116, 255, 0.36);
}
.categoryTabActive:hover {
background: linear-gradient(135deg, var(--accent) 0%, var(--accent2) 100%);
color: #fff;
transform: translateY(-1px);
}
.categoryCount {
background: rgba(255, 255, 255, 0.20);
padding: 1px 8px;
border-radius: 999px;
font-size: 11px;
font-weight: 800;
}
.categoryTab:not(.categoryTabActive) .categoryCount {
background: rgba(255, 255, 255, 0.08);
color: var(--text-dim);
}
/* === Сетка карточек === */
.grid {
flex: 1;
overflow-y: auto;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
grid-auto-rows: min-content;
gap: 8px;
padding: 14px;
align-content: start;
}
.empty {
grid-column: 1 / -1;
text-align: center;
color: var(--text-dim);
padding: 60px 20px;
font-size: 14px;
}
.card {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 6px;
padding: 14px 10px;
background: var(--bg-mid);
border: 1px solid var(--border);
border-radius: 12px;
color: var(--text);
cursor: pointer;
transition: all 200ms cubic-bezier(0.34, 1.56, 0.64, 1);
min-height: 120px;
font-family: inherit;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
}
.card:hover {
transform: translateY(-3px);
border-color: var(--accent);
box-shadow: 0 12px 24px rgba(79, 116, 255, 0.25);
}
.cardActive {
border-color: var(--accent);
background: rgba(79, 116, 255, 0.18);
box-shadow: 0 0 0 2px var(--accent), 0 8px 20px rgba(79, 116, 255, 0.35);
}
.cardIcon {
font-size: 32px;
line-height: 1;
}
.cardName {
font-size: 11px;
line-height: 1.2;
text-align: center;
color: var(--text);
word-break: break-word;
}
.cardCat {
font-size: 10px;
color: var(--text-dim);
}
.cardActive .cardName {
color: var(--accent-bright);
font-weight: 800;
}
/* === Этап 6.3: социальная строка карточки (лайки + использования) === */
.cardSocial {
display: flex;
align-items: center;
justify-content: space-between;
gap: 6px;
margin-top: 4px;
}
.cardLikeBtn {
display: inline-flex;
align-items: center;
gap: 4px;
padding: 3px 8px;
font-size: 11px;
font-weight: 700;
border: 1px solid var(--border);
border-radius: 999px;
background: var(--bg-light);
color: var(--text-dim);
cursor: pointer;
transition: all 0.12s;
}
.cardLikeBtn:hover {
border-color: #ff5577;
color: #ff5577;
}
.cardLikeActive {
border-color: #ff5577;
background: #ff5577;
color: #fff;
}
.cardLikeActive:hover {
color: #fff;
}
.cardUses {
display: inline-flex;
align-items: center;
gap: 3px;
font-size: 11px;
font-weight: 600;
color: var(--text-dim);
}
.cardBadge {
position: absolute;
top: 6px;
right: 6px;
font-size: 13px;
background: linear-gradient(135deg, var(--accent) 0%, var(--accent2) 100%);
color: #fff;
padding: 3px 8px;
border-radius: 999px;
font-weight: 800;
box-shadow: 0 2px 6px rgba(79, 116, 255, 0.36);
}
/* === Этап 6: hover-overlay для управления своими моделями === */
.userCard {
/* div вместо button — нужно убрать button-defaults */
background: var(--bg-mid);
user-select: none;
}
.userCard:focus {
outline: 2px solid var(--accent);
outline-offset: 2px;
}
.cardActions {
position: absolute;
top: 6px;
left: 6px;
display: flex;
gap: 4px;
opacity: 0;
transform: translateY(-4px);
transition: opacity 150ms ease, transform 150ms ease;
pointer-events: none;
}
.userCard:hover .cardActions,
.userCard:focus-within .cardActions {
opacity: 1;
transform: translateY(0);
pointer-events: auto;
}
.cardActionBtn {
display: inline-flex;
align-items: center;
justify-content: center;
width: 26px;
height: 26px;
background: var(--bg-light);
border: 1px solid var(--border);
border-radius: 7px;
color: var(--text);
cursor: pointer;
transition: all 120ms ease;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.4);
font-family: inherit;
padding: 0;
}
.cardActionBtn:hover {
background: var(--accent);
border-color: var(--accent);
color: #fff;
transform: scale(1.08);
}
.cardActionDanger:hover {
background: #ef4444;
border-color: #ef4444;
color: #fff;
}
.cardThumb {
width: 100%;
height: 80px;
object-fit: contain;
/* Белый фон для превью моделей — модели и текстуры читаются лучше
на светлом, особенно тёмные/чёрные (камни, металл). 2026-05-27. */
background: #fff;
border-radius: 8px;
image-rendering: auto;
}
.cardIconPlaceholder {
width: 100%;
height: 80px;
display: flex;
align-items: center;
justify-content: center;
background: #fff;
border-radius: 8px;
font-size: 36px;
color: var(--text-dim);
}
/* ====================== Roblox-style Toolbox (задача 17) ======================
Явные светлые цвета (не --text-переменные — они в этой модалке не заданы и
давали тёмный текст на тёмном фоне). Крупнее шрифты. */
.topTabs {
display: flex;
gap: 4px;
padding: 0 16px;
border-bottom: 1px solid rgba(255,255,255,0.10);
flex: 0 0 auto;
}
.topTab {
flex: 1;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
gap: 8px;
padding: 14px 4px 12px;
background: none;
border: none;
border-bottom: 2px solid transparent;
color: #aab2c0;
font-size: 15px;
font-weight: 600;
cursor: pointer;
transition: color .12s, border-color .12s;
}
.topTab:hover { color: #ffffff; }
.topTabActive {
color: #6f8bff;
border-bottom-color: #6f8bff;
}
.breadcrumb {
display: flex;
align-items: center;
gap: 12px;
padding: 12px 18px 6px;
flex: 0 0 auto;
}
.backBtn {
display: inline-flex;
align-items: center;
gap: 6px;
background: rgba(255,255,255,0.08);
border: 1px solid rgba(255,255,255,0.14);
color: #e8ecf2;
padding: 7px 14px;
border-radius: 9px;
font-size: 14px;
font-weight: 600;
cursor: pointer;
}
.backBtn:hover { background: rgba(255,255,255,0.15); }
.crumbCurrent { font-weight: 700; font-size: 15px; color: #ffffff; }
.storeHome { overflow-y: auto; padding: 16px 20px 22px; flex: 1; }
.sectionLabel {
display: flex; align-items: center; gap: 8px;
font-weight: 700; font-size: 17px; color: #ffffff;
margin-bottom: 14px;
}
.sectionLabel svg { color: #6f8bff; }
.catGrid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 14px;
}
.catTile {
display: grid;
grid-template-columns: auto 1fr;
grid-template-rows: auto auto;
column-gap: 14px;
row-gap: 4px;
align-items: center;
padding: 18px 20px;
background: rgba(255,255,255,0.06);
border: 1px solid rgba(255,255,255,0.10);
border-radius: 14px;
cursor: pointer;
text-align: left;
transition: transform .1s, background .12s, border-color .12s;
}
.catTile:hover {
background: rgba(111,139,255,0.16);
border-color: #6f8bff;
transform: translateY(-2px);
}
/* Иконка — слева, занимает обе строки (в одну линию с названием). */
.catTileIcon {
grid-row: 1 / 3;
display: flex; align-items: center; justify-content: center;
width: 52px; height: 52px;
background: rgba(111,139,255,0.16);
border-radius: 12px;
color: #8aa0ff;
}
.catTileLabel { font-weight: 800; font-size: 18px; color: #ffffff; align-self: end; }
.catTileDesc { font-size: 13px; color: #aab2c0; line-height: 1.35; align-self: start; }
.trendRow {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 14px;
}
.trendCard {
position: relative;
display: flex; flex-direction: column; align-items: center; gap: 10px;
padding: 14px 10px 16px;
background: rgba(255,255,255,0.06);
border: 1px solid rgba(255,255,255,0.10);
border-radius: 14px;
cursor: pointer;
transition: transform .1s, border-color .12s;
}
.trendCard:hover { transform: translateY(-2px); border-color: #6f8bff; }
.trendIcon {
width: 100%; height: 78px;
display: flex; align-items: center; justify-content: center;
background: linear-gradient(135deg, rgba(111,139,255,0.28), rgba(54,213,122,0.18));
border-radius: 10px;
color: #ffffff;
}
.trendName { font-size: 14px; font-weight: 700; text-align: center; color: #ffffff; }
.freeBadge {
position: absolute; top: 10px; right: 10px;
font-size: 10px; font-weight: 800; letter-spacing: 0.5px;
color: #3ce087;
background: rgba(54,213,122,0.18);
padding: 3px 7px; border-radius: 6px;
}
.soon {
flex: 1;
display: flex; flex-direction: column; align-items: center; justify-content: center;
gap: 12px; padding: 50px;
color: #aab2c0; text-align: center;
}
.soon svg { color: #6f8bff; }
.soonTitle { font-size: 22px; font-weight: 800; color: #ffffff; }
.soonText { font-size: 15px; max-width: 400px; color: #aab2c0; line-height: 1.5; }
.tips {
overflow-y: auto; padding: 22px 28px; flex: 1;
color: #e8ecf2; line-height: 1.6;
}
.tips h3 { margin: 4px 0 16px; font-size: 21px; color: #ffffff; }
.tips ul { margin: 0 0 18px; padding-left: 22px; }
.tips li { margin-bottom: 12px; font-size: 15px; color: #d4dae4; }
.tips b { color: #8aa0ff; }
.tips p { font-size: 14px; }