+ {/* === Шапка с 4 верхними вкладками (как Roblox Creator Store) === */}
- {/* Раздел: Стандартные / Мои / Сообщество */}
-
-
-
-
-
+
+ {[
+ { id: 'store', label: 'Магазин', icon: 'box' },
+ { id: 'inventory', label: 'Инвентарь', icon: 'grid' },
+ { id: 'recent', label: 'Недавние', icon: 'clock' },
+ { id: 'tips', label: 'Советы', icon: 'bulb' },
+ ].map(t => (
+
+ ))}
-
- setSearch(e.target.value)}
- autoFocus
- />
-
+ {/* Поиск — скрыт только на главном экране магазина и в советах */}
+ {!(view === 'store' && !storeCat) && view !== 'tips' && (
+
+ setSearch(e.target.value)}
+ autoFocus
+ />
+
+ )}
- {/* Подкатегории зависят от раздела */}
- {section === 'standard' && (
+ {/* Хлебные крошки/назад при открытой категории магазина */}
+ {view === 'store' && storeCat && (
+
+
+
+ {(STORE_CATEGORIES.find(c => c.id === storeCat) || {}).label}
+
+
+ )}
+
+ {/* Подкатегории standard (3D) */}
+ {view === 'store' && storeCat === '3d' && (
{standardCategoriesWithCount.map(c => (
);
diff --git a/src/editor/ToolboxModal.module.css b/src/editor/ToolboxModal.module.css
index df93cf3..40b2c5f 100644
--- a/src/editor/ToolboxModal.module.css
+++ b/src/editor/ToolboxModal.module.css
@@ -447,3 +447,134 @@
font-size: 36px;
color: var(--text-dim);
}
+
+/* ====================== Roblox-style Toolbox (задача 17) ====================== */
+.topTabs {
+ display: flex;
+ gap: 2px;
+ padding: 0 14px;
+ border-bottom: 1px solid var(--border, rgba(255,255,255,0.08));
+ flex: 0 0 auto;
+}
+.topTab {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 3px;
+ padding: 10px 4px 8px;
+ background: none;
+ border: none;
+ border-bottom: 2px solid transparent;
+ color: var(--text-dim, #9aa3b2);
+ font-size: 12px;
+ cursor: pointer;
+ transition: color .12s, border-color .12s;
+}
+.topTab:hover { color: var(--text, #e8ecf2); }
+.topTabActive {
+ color: var(--accent, #4d6bff);
+ border-bottom-color: var(--accent, #4d6bff);
+}
+
+.breadcrumb {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ padding: 8px 16px 4px;
+ flex: 0 0 auto;
+}
+.backBtn {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+ background: rgba(255,255,255,0.06);
+ border: 1px solid rgba(255,255,255,0.1);
+ color: var(--text, #e8ecf2);
+ padding: 5px 10px;
+ border-radius: 8px;
+ font-size: 13px;
+ cursor: pointer;
+}
+.backBtn:hover { background: rgba(255,255,255,0.12); }
+.crumbCurrent { font-weight: 700; color: var(--text, #e8ecf2); }
+
+.storeHome { overflow-y: auto; padding: 12px 16px 18px; flex: 1; }
+.sectionLabel {
+ display: flex; align-items: center; gap: 6px;
+ font-weight: 700; font-size: 14px; color: var(--text, #e8ecf2);
+ margin-bottom: 10px;
+}
+.catGrid {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ gap: 12px;
+}
+.catTile {
+ display: flex; flex-direction: column; align-items: flex-start; gap: 4px;
+ padding: 16px;
+ background: rgba(255,255,255,0.05);
+ border: 1px solid rgba(255,255,255,0.09);
+ border-radius: 12px;
+ cursor: pointer;
+ text-align: left;
+ transition: transform .1s, background .12s, border-color .12s;
+}
+.catTile:hover {
+ background: rgba(77,107,255,0.12);
+ border-color: var(--accent, #4d6bff);
+ transform: translateY(-2px);
+}
+.catTileIcon { color: var(--accent, #4d6bff); margin-bottom: 4px; }
+.catTileLabel { font-weight: 700; font-size: 15px; color: var(--text, #e8ecf2); }
+.catTileDesc { font-size: 11px; opacity: 0.7; line-height: 1.3; }
+
+.trendRow {
+ display: grid;
+ grid-template-columns: repeat(4, 1fr);
+ gap: 12px;
+}
+.trendCard {
+ position: relative;
+ display: flex; flex-direction: column; align-items: center; gap: 8px;
+ padding: 14px 8px;
+ background: rgba(255,255,255,0.05);
+ border: 1px solid rgba(255,255,255,0.09);
+ border-radius: 12px;
+ cursor: pointer;
+ transition: transform .1s, border-color .12s;
+}
+.trendCard:hover { transform: translateY(-2px); border-color: var(--accent, #4d6bff); }
+.trendIcon {
+ width: 100%; height: 70px;
+ display: flex; align-items: center; justify-content: center;
+ background: linear-gradient(135deg, rgba(77,107,255,0.22), rgba(54,213,122,0.16));
+ border-radius: 8px;
+ color: var(--text, #e8ecf2);
+}
+.trendName { font-size: 12px; font-weight: 600; text-align: center; color: var(--text, #e8ecf2); }
+.freeBadge {
+ position: absolute; top: 8px; right: 8px;
+ font-size: 9px; font-weight: 800; letter-spacing: 0.5px;
+ color: #36d57a;
+ background: rgba(54,213,122,0.14);
+ padding: 2px 6px; border-radius: 6px;
+}
+
+.soon {
+ flex: 1;
+ display: flex; flex-direction: column; align-items: center; justify-content: center;
+ gap: 10px; padding: 40px;
+ color: var(--text-dim, #9aa3b2); text-align: center;
+}
+.soonTitle { font-size: 18px; font-weight: 700; color: var(--text, #e8ecf2); }
+.soonText { font-size: 13px; max-width: 360px; opacity: 0.75; }
+
+.tips {
+ overflow-y: auto; padding: 16px 22px; flex: 1;
+ color: var(--text, #e8ecf2); line-height: 1.55;
+}
+.tips h3 { margin: 4px 0 12px; font-size: 17px; }
+.tips ul { margin: 0 0 14px; padding-left: 18px; }
+.tips li { margin-bottom: 9px; font-size: 13px; }
+.tips b { color: var(--accent, #6f8bff); }
diff --git a/src/editor/TopRibbon.jsx b/src/editor/TopRibbon.jsx
index 5966394..94ed199 100644
--- a/src/editor/TopRibbon.jsx
+++ b/src/editor/TopRibbon.jsx
@@ -140,10 +140,12 @@ const Dropdown = ({ trigger, children }) => {
*/
const TABS = [
- { id: 'home', label: 'Главная', iconName: 'home' },
- { id: 'model', label: 'Модель', iconName: 'wrench' },
- { id: 'test', label: 'Игра', iconName: 'gamepad' },
- { id: 'view', label: 'Вид', iconName: 'eye' },
+ { id: 'home', label: 'Главная', iconName: 'home' },
+ // Вкладка-редактор СВОИХ воксельных моделей (создание ассета).
+ // Каталог готовых моделей/механик теперь в Toolbox (кнопка на «Главной»).
+ { id: 'model', label: 'Редактор моделей', iconName: 'wrench' },
+ { id: 'test', label: 'Игра', iconName: 'gamepad' },
+ { id: 'view', label: 'Вид', iconName: 'eye' },
];
const SNAP_OPTIONS = [
@@ -329,9 +331,9 @@ const TopRibbon = (props) => {
title="Параметрическая фигура (куб/сфера/...)"
/>
onToolChange('model')}
+ iconName="box" label="Toolbox"
+ onClick={onOpenStandardModels}
+ title="Библиотека: 3D-объекты, готовые механики, эффекты (как Creator Store)"
/>