Compare commits

...

5 Commits

66 changed files with 1614 additions and 606 deletions

View File

@@ -10,16 +10,31 @@ dist
# Local Codex/dev artifacts # Local Codex/dev artifacts
.codex* .codex*
.codex/ .codex/
.codex-dev.*
.codex-cache/
.tmp* .tmp*
*.tmp *.tmp
# Logs # Logs and runtime junk
*.log *.log
*.log.*
*.out
*.err
*.pid
*.pid.lock
logs
preview*.log
npm-debug.log* npm-debug.log*
yarn-debug.log* yarn-debug.log*
yarn-error.log* yarn-error.log*
pnpm-debug.log* pnpm-debug.log*
# Env and local-only config
.env
.env.*
!.env.example
*.local
# OS/editor files # OS/editor files
.DS_Store .DS_Store
Thumbs.db Thumbs.db
@@ -31,3 +46,9 @@ Thumbs.db
# Local caches # Local caches
tmp tmp
.cache .cache
temp
coverage
.nyc_output
.pnpm-store
.npm
*.tsbuildinfo

25
.gitignore vendored
View File

@@ -5,16 +5,31 @@ dist/
# Local Codex/dev artifacts # Local Codex/dev artifacts
.codex* .codex*
.codex/ .codex/
.codex-dev.*
.codex-cache/
.tmp* .tmp*
*.tmp *.tmp
# Logs # Logs
*.log *.log
*.log.*
*.out
*.err
*.pid
*.pid.lock
logs/
preview*.log
npm-debug.log* npm-debug.log*
yarn-debug.log* yarn-debug.log*
yarn-error.log* yarn-error.log*
pnpm-debug.log* pnpm-debug.log*
# Env and local-only config
.env
.env.*
!.env.example
*.local
# OS files # OS files
.DS_Store .DS_Store
Thumbs.db Thumbs.db
@@ -24,3 +39,13 @@ Thumbs.db
.idea/ .idea/
*.swp *.swp
*.swo *.swo
# Caches / tooling
.cache/
tmp/
temp/
coverage/
.nyc_output/
.pnpm-store/
.npm/
*.tsbuildinfo

93
Makefile Normal file
View File

@@ -0,0 +1,93 @@
# ================================
# Настройки
# ================================
COMPOSE=docker compose
SERVICE=primoguard
# Список команд
.PHONY: help install dev build preview up down restart logs pull update ps shell clean prune tunnel
# ================================
# Помощь
# ================================
help:
@echo "Доступные команды:"
@echo " make install - установить npm зависимости"
@echo " make dev - локальный запуск Astro для разработки"
@echo " make build - продакшн сборка Astro"
@echo " make preview - предпросмотр продакшн сборки"
@echo " make up - поднять Docker контейнер"
@echo " make down - остановить Docker контейнер"
@echo " make restart - перезапустить Docker контейнер"
@echo " make logs - смотреть логи Docker"
@echo " make pull - обновить проект через git pull"
@echo " make update - обновить проект и перезапустить Docker"
@echo " make ps - список контейнеров"
@echo " make shell - зайти внутрь контейнера"
@echo " make clean - остановить контейнер"
@echo " make prune - очистить Docker мусор"
@echo " make tunnel - запустить Cloudflare Tunnel"
# ================================
# Локальная разработка
# ================================
install:
npm install
dev:
npm run dev
build:
npm run build
preview:
npm run preview
# ================================
# Docker
# ================================
up:
$(COMPOSE) up -d --build
down:
$(COMPOSE) down
restart:
$(COMPOSE) down
$(COMPOSE) up -d --build
logs:
$(COMPOSE) logs -f
ps:
$(COMPOSE) ps
shell:
docker exec -it $(SERVICE) sh
# ================================
# Git + Docker
# ================================
pull:
git pull
update:
$(COMPOSE) down
git pull
$(COMPOSE) up -d --build
$(COMPOSE) logs -f
# ================================
# Очистка
# ================================
clean:
$(COMPOSE) down
prune:
docker system prune -f
# ================================
# Публичный доступ
# ================================
tunnel:
cloudflared tunnel --url http://127.0.0.1:4321 --protocol http2 --edge-ip-version 4

View File

@@ -1,6 +1,7 @@
import { defineConfig } from 'astro/config'; import { defineConfig } from 'astro/config';
import starlight from '@astrojs/starlight'; import starlight from '@astrojs/starlight';
export default defineConfig({ export default defineConfig({
site: 'https://wiki.example.com', site: 'https://wiki.example.com',
vite: { vite: {
@@ -25,6 +26,7 @@ export default defineConfig({
} }
}, },
tagline: 'Нереалистичный архив игрового мира', tagline: 'Нереалистичный архив игрового мира',
favicon: '/photo_2026-03-14_11-18-15.jpg',
customCss: ['/src/styles/wiki-egames.css'], customCss: ['/src/styles/wiki-egames.css'],
lastUpdated: true, lastUpdated: true,
disable404Route: true, disable404Route: true,
@@ -45,22 +47,24 @@ export default defineConfig({
label: 'О сервере', label: 'О сервере',
items: [ items: [
{ label: 'Главная', link: '/' }, { label: 'Главная', link: '/' },
{ label: 'Сюжет', link: '/story/' },
{ label: 'Начало игры', link: '/getting-started/' } { label: 'Начало игры', link: '/getting-started/' }
] ]
}, },
{ {
label: 'Введение', label: 'Введение',
items: [ items: [
{ label: 'Часто задаваемые вопросы', link: '/faq/' }, { label: 'О проекте', link: '/about-server/' },
{ label: 'Правила', link: '/rules/' } { label: 'Правила', link: '/rules/' },
{ label: 'Часто задаваемые вопросы', link: '/faq/' }
] ]
}, },
{ {
label: 'Игровые системы', label: 'Игровые системы',
items: [ items: [
{ label: 'Общее', link: '/general/' }, { label: 'Общее', link: '/general/' },
{ label: 'Команды', link: '/commands/' },
{ label: 'Города', link: '/cities/' }, { label: 'Города', link: '/cities/' },
{ label: 'Крафты', link: '/crafting/' },
{ {
label: 'Алкоголь', label: 'Алкоголь',
items: [ items: [
@@ -72,18 +76,11 @@ export default defineConfig({
] ]
}, },
{ {
label: 'Техническое', label: 'Тех. Информация',
items: [ items: [
{ label: 'Все IP', link: '/all-ip/' }, { label: 'Все IP', link: '/all-ip/' },
{ label: 'Контакты и ссылки', link: '/contacts/' } { label: 'Контакты и ссылки', link: '/contacts/' }
] ]
},
{
label: 'Для редакторов',
items: [
{ label: 'Как редактировать wiki', link: '/editing/' },
{ label: 'Шаблон новой страницы', link: '/templates/new-page-template/' }
]
} }
] ]
}) })

View File

@@ -1,11 +1,15 @@
name: parabox-wiki
services: services:
wiki: wiki:
build: build:
context: . context: .
dockerfile: Dockerfile dockerfile: Dockerfile
container_name: parabox-wiki container_name: parabox-wiki
ports: #ports:
- "4321:80" #- "4321:80"
restart: unless-stopped restart: unless-stopped
networks:
- proxy
networks:
proxy:
external: true

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

BIN
public/brand-logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
public/crafts/bell.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
public/crafts/bundle.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
public/crafts/dispenser.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

BIN
public/crafts/jukebox.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
public/crafts/loom.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
public/crafts/name-tag.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -2,10 +2,11 @@
import { Icon } from '@astrojs/starlight/components'; import { Icon } from '@astrojs/starlight/components';
const { editUrl } = Astro.locals.starlightRoute; const { editUrl } = Astro.locals.starlightRoute;
const showEditorDocs = import.meta.env.PUBLIC_SHOW_EDITOR_DOCS === 'true';
--- ---
{ {
editUrl && ( showEditorDocs && editUrl && (
<a href={editUrl} class="wiki-edit-link sl-flex print:hidden" target="_blank" rel="noopener noreferrer"> <a href={editUrl} class="wiki-edit-link sl-flex print:hidden" target="_blank" rel="noopener noreferrer">
<Icon name="pencil" size="1.05em" /> <Icon name="pencil" size="1.05em" />
Редактировать страницу Редактировать страницу

View File

@@ -3,7 +3,6 @@ import config from 'virtual:starlight/user-config';
import LanguageSelect from 'virtual:starlight/components/LanguageSelect'; import LanguageSelect from 'virtual:starlight/components/LanguageSelect';
import Search from 'virtual:starlight/components/Search'; import Search from 'virtual:starlight/components/Search';
import SiteTitle from 'virtual:starlight/components/SiteTitle';
import SocialIcons from 'virtual:starlight/components/SocialIcons'; import SocialIcons from 'virtual:starlight/components/SocialIcons';
const shouldRenderSearch = const shouldRenderSearch =
@@ -11,8 +10,8 @@ const shouldRenderSearch =
const topLinks = [ const topLinks = [
{ label: 'Старт', href: '/getting-started/' }, { label: 'Старт', href: '/getting-started/' },
{ label: 'Гайды', href: '/guides/' }, { label: 'Команды', href: '/commands/' },
{ label: 'Механики', href: '/mechanics/' }, { label: 'Города', href: '/cities/' },
{ label: 'FAQ', href: '/faq/' }, { label: 'FAQ', href: '/faq/' },
{ label: 'Правила', href: '/rules/' } { label: 'Правила', href: '/rules/' }
]; ];
@@ -21,7 +20,15 @@ const topLinks = [
<div class="wiki-header-shell"> <div class="wiki-header-shell">
<div class="header wiki-header"> <div class="header wiki-header">
<div class="title-wrapper sl-flex"> <div class="title-wrapper sl-flex">
<SiteTitle /> <a class="wiki-brand" href="/" aria-label="PARABOX PROJECT">
<span class="wiki-brand__icon" aria-hidden="true">
<img src="/brand-logo.png" alt="" loading="eager" decoding="async" />
</span>
<span class="wiki-brand__copy">
<span class="wiki-brand__title">PARABOX</span>
<span class="wiki-brand__subtitle">PROJECT</span>
</span>
</a>
<nav class="wiki-top-nav" aria-label="Быстрая навигация"> <nav class="wiki-top-nav" aria-label="Быстрая навигация">
{ {
topLinks.map((link) => ( topLinks.map((link) => (
@@ -89,12 +96,339 @@ const topLinks = [
</div> </div>
<button class="wiki-back-to-top" type="button" aria-label="Прокрутить в начало" data-back-to-top> <button class="wiki-back-to-top" type="button" aria-label="Прокрутить в начало" data-back-to-top>
<span aria-hidden="true">↑</span> <svg aria-hidden="true" class="wiki-back-to-top__icon" viewBox="0 0 24 24" fill="none">
<path d="M12 18V6" />
<path d="m6.8 11.2 5.2-5.2 5.2 5.2" />
</svg>
</button> </button>
<script> <script>
const emojiPattern = (() => {
try {
return new RegExp('[\\p{Extended_Pictographic}\\u2600-\\u27BF]', 'gu');
} catch {
return /[\u2600-\u27BF]/g;
}
})();
const stripDecorativeSymbols = (value) =>
value
.replace(emojiPattern, '')
.replace(/\s{2,}/g, ' ')
.trim();
const normalizeLabelKey = (value) => stripDecorativeSymbols(value).toLowerCase();
const minimalIconByHeading = new Map([
['настройки', '/icons/minimal-solid/gear.png'],
['личные сообщения', '/icons/minimal-solid/message.png'],
['игнор', '/icons/minimal-solid/safe.png'],
['развлечения', '/icons/minimal-solid/game-controller.png'],
['rp и взаимодействие', '/icons/minimal-solid/community.png'],
['статус игрока', '/icons/minimal-solid/user-profile.png'],
['информация', '/icons/minimal-solid/exclamation.png'],
['символы', '/icons/minimal-solid/keyboard.png']
]);
const sanitizeNavLabels = () => {
const navLinks = document.querySelectorAll('.sidebar-content a, starlight-toc a, mobile-starlight-toc a');
navLinks.forEach((linkNode) => {
if (!(linkNode instanceof HTMLElement)) return;
const sourceText = linkNode.textContent;
if (!sourceText) return;
const normalizedText = stripDecorativeSymbols(sourceText);
if (!normalizedText || normalizedText === sourceText.trim()) return;
linkNode.textContent = normalizedText;
});
};
const sanitizeDocHeadings = () => {
const headings = document.querySelectorAll('.sl-markdown-content :is(h1, h2, h3, h4, h5, h6)');
headings.forEach((headingNode) => {
if (!(headingNode instanceof HTMLElement)) return;
const sourceText = headingNode.textContent;
if (!sourceText) return;
const normalizedText = stripDecorativeSymbols(sourceText);
if (!normalizedText || normalizedText === sourceText.trim()) return;
headingNode.textContent = normalizedText;
});
};
const decorateSectionIcons = () => {
const headings = document.querySelectorAll('.sl-markdown-content h3');
headings.forEach((headingNode) => {
if (!(headingNode instanceof HTMLElement)) return;
const sourceText = headingNode.textContent;
if (!sourceText) return;
const normalizedText = normalizeLabelKey(sourceText);
const iconPath = minimalIconByHeading.get(normalizedText);
if (!iconPath) return;
if (headingNode.querySelector('.minimal-heading-icon')) return;
const iconNode = document.createElement('span');
iconNode.className = 'minimal-heading-icon';
iconNode.setAttribute('aria-hidden', 'true');
iconNode.style.setProperty('--icon-url', `url('${iconPath}')`);
headingNode.prepend(iconNode);
});
};
const trimDestination = (value, maxLength = 42) => {
if (value.length <= maxLength) return value;
return `${value.slice(0, Math.max(0, maxLength - 1))}…`;
};
const decodePath = (value) => {
try {
return decodeURIComponent(value);
} catch {
return value;
}
};
const annotateLinkDestinations = () => {
const links = document.querySelectorAll('a[href]');
links.forEach((linkNode) => {
if (!(linkNode instanceof HTMLAnchorElement)) return;
if (linkNode.dataset.linkAnnotated === 'true') return;
const rawHref = linkNode.getAttribute('href')?.trim();
if (!rawHref || rawHref.toLowerCase().startsWith('javascript:')) return;
let parsedUrl;
try {
parsedUrl = new URL(rawHref, window.location.href);
} catch {
return;
}
const isHashOnly = rawHref.startsWith('#');
const isHttp = parsedUrl.protocol === 'http:' || parsedUrl.protocol === 'https:';
const isMail = parsedUrl.protocol === 'mailto:';
const isTel = parsedUrl.protocol === 'tel:';
const isExternal = isHttp && parsedUrl.origin !== window.location.origin;
const isSamePageAnchor =
!isExternal && !!parsedUrl.hash && parsedUrl.pathname === window.location.pathname;
const isContentLink = linkNode.closest('.sl-markdown-content') instanceof HTMLElement;
const shouldDecorate =
isContentLink &&
!isHashOnly &&
!linkNode.classList.contains('sl-anchor-link') &&
!linkNode.classList.contains('map-cta-button') &&
!linkNode.classList.contains('map-ghost-button') &&
!linkNode.classList.contains('sl-link-button');
if (shouldDecorate) {
let kind = 'internal';
if (isExternal) kind = 'external';
else if (isMail) kind = 'mail';
else if (isTel) kind = 'tel';
else if (isSamePageAnchor) kind = 'anchor';
linkNode.dataset.linkKind = kind;
let destination = '';
if (isExternal) destination = parsedUrl.hostname.replace(/^www\./, '');
else if (isMail) destination = rawHref.replace(/^mailto:/i, '');
else if (isTel) destination = rawHref.replace(/^tel:/i, '');
else destination = `${decodePath(parsedUrl.pathname)}${parsedUrl.hash || ''}`;
if (destination) {
linkNode.dataset.linkDestination = trimDestination(destination);
}
}
if (isExternal) {
const relValues = new Set((linkNode.rel || '').split(/\s+/).filter(Boolean));
relValues.add('noopener');
relValues.add('noreferrer');
linkNode.rel = Array.from(relValues).join(' ');
if (!linkNode.target) {
linkNode.target = '_blank';
}
}
if (!linkNode.title) {
if (isHashOnly || isSamePageAnchor) {
linkNode.title = `Переход к разделу: ${parsedUrl.hash || rawHref}`;
} else if (isExternal) {
linkNode.title = `Внешняя ссылка: ${parsedUrl.hostname.replace(/^www\./, '')}`;
} else if (isMail) {
linkNode.title = `Написать: ${rawHref.replace(/^mailto:/i, '')}`;
} else if (isTel) {
linkNode.title = `Позвонить: ${rawHref.replace(/^tel:/i, '')}`;
} else {
linkNode.title = `Перейти: ${decodePath(parsedUrl.pathname)}${parsedUrl.hash || ''}`;
}
}
linkNode.dataset.linkAnnotated = 'true';
});
};
const copyTextToClipboard = async (value) => {
if (navigator.clipboard?.writeText) {
await navigator.clipboard.writeText(value);
return;
}
const helperInput = document.createElement('textarea');
helperInput.value = value;
helperInput.setAttribute('readonly', '');
helperInput.style.position = 'fixed';
helperInput.style.opacity = '0';
document.body.appendChild(helperInput);
helperInput.select();
document.execCommand('copy');
helperInput.remove();
};
const bindCopyIpChips = () => {
const copyButtons = document.querySelectorAll('[data-copy-ip]');
copyButtons.forEach((buttonNode) => {
if (!(buttonNode instanceof HTMLButtonElement)) return;
if (buttonNode.dataset.copyBound === 'true') return;
buttonNode.dataset.copyBound = 'true';
buttonNode.classList.add('is-copy-ready');
if (!buttonNode.title) {
buttonNode.title = 'Нажмите, чтобы скопировать';
}
buttonNode.addEventListener('click', async () => {
const value = buttonNode.dataset.copyIp?.trim();
if (!value) return;
try {
await copyTextToClipboard(value);
buttonNode.classList.add('is-copied');
buttonNode.setAttribute('aria-label', `Скопировано: ${value}`);
window.setTimeout(() => {
buttonNode.classList.remove('is-copied');
buttonNode.setAttribute('aria-label', `Скопировать: ${value}`);
}, 1200);
} catch {
buttonNode.classList.add('is-copy-error');
buttonNode.setAttribute('aria-label', `Не удалось скопировать: ${value}`);
window.setTimeout(() => {
buttonNode.classList.remove('is-copy-error');
buttonNode.setAttribute('aria-label', `Скопировать: ${value}`);
}, 1400);
}
});
});
};
const normalizeCraftSearch = (value) =>
stripDecorativeSymbols(value)
.toLowerCase()
.replace(/ё/g, 'е')
.replace(/\s+/g, ' ')
.trim();
const bindCraftCatalogFilters = () => {
const catalogNodes = document.querySelectorAll('[data-craft-catalog]');
catalogNodes.forEach((catalogNode) => {
if (!(catalogNode instanceof HTMLElement)) return;
if (catalogNode.dataset.craftBound === 'true') return;
catalogNode.dataset.craftBound = 'true';
const searchInput = catalogNode.querySelector('[data-craft-search]');
const filterButtons = Array.from(catalogNode.querySelectorAll('[data-craft-filter]')).filter(
(node) => node instanceof HTMLButtonElement
);
const groupNodes = Array.from(catalogNode.querySelectorAll('[data-craft-group]')).filter(
(node) => node instanceof HTMLElement
);
const emptyState = catalogNode.querySelector('[data-craft-empty]');
let activeFilter = 'all';
const activeButton = filterButtons.find(
(buttonNode) =>
buttonNode.classList.contains('is-active') ||
buttonNode.getAttribute('aria-pressed') === 'true'
);
if (activeButton?.dataset.craftFilter) {
activeFilter = activeButton.dataset.craftFilter;
}
const applyFilters = () => {
const searchQuery =
searchInput instanceof HTMLInputElement ? normalizeCraftSearch(searchInput.value) : '';
filterButtons.forEach((buttonNode) => {
const isActive = (buttonNode.dataset.craftFilter || 'all') === activeFilter;
buttonNode.classList.toggle('is-active', isActive);
buttonNode.setAttribute('aria-pressed', String(isActive));
});
let visibleCount = 0;
groupNodes.forEach((groupNode) => {
const defaultCategory = groupNode.dataset.craftCategory || '';
const itemNodes = Array.from(groupNode.querySelectorAll('[data-craft-item]')).filter(
(node) => node instanceof HTMLElement
);
let groupVisibleCount = 0;
itemNodes.forEach((itemNode) => {
const itemCategory = itemNode.dataset.craftCategory || defaultCategory;
const itemName =
itemNode.dataset.craftName || itemNode.querySelector('h3')?.textContent || '';
const normalizedName = normalizeCraftSearch(itemName);
const matchesCategory = activeFilter === 'all' || itemCategory === activeFilter;
const matchesSearch = !searchQuery || normalizedName.includes(searchQuery);
const isVisible = matchesCategory && matchesSearch;
itemNode.hidden = !isVisible;
if (isVisible) groupVisibleCount += 1;
});
groupNode.hidden = groupVisibleCount === 0;
visibleCount += groupVisibleCount;
});
if (emptyState instanceof HTMLElement) {
emptyState.hidden = visibleCount > 0;
}
};
filterButtons.forEach((buttonNode) => {
buttonNode.addEventListener('click', () => {
const nextFilter = buttonNode.dataset.craftFilter || 'all';
if (nextFilter === activeFilter) return;
activeFilter = nextFilter;
applyFilters();
});
});
if (searchInput instanceof HTMLInputElement) {
searchInput.addEventListener('input', applyFilters);
searchInput.addEventListener('search', applyFilters);
}
applyFilters();
});
};
const enhanceSidebarGroupLinks = () => { const enhanceSidebarGroupLinks = () => {
const targets = [{ label: 'Алкоголь', href: '/alcohol/' }]; const targets = [];
if (targets.length === 0) return;
const labelNodes = document.querySelectorAll('.sidebar-content details > summary .group-label .large'); const labelNodes = document.querySelectorAll('.sidebar-content details > summary .group-label .large');
labelNodes.forEach((labelNode) => { labelNodes.forEach((labelNode) => {
@@ -164,6 +498,12 @@ const topLinks = [
}); });
enhanceSidebarGroupLinks(); enhanceSidebarGroupLinks();
sanitizeNavLabels();
sanitizeDocHeadings();
decorateSectionIcons();
annotateLinkDestinations();
bindCopyIpChips();
bindCraftCatalogFilters();
setReadProgress(); setReadProgress();
window.addEventListener('scroll', setReadProgress, { passive: true }); window.addEventListener('scroll', setReadProgress, { passive: true });
window.addEventListener('resize', setReadProgress); window.addEventListener('resize', setReadProgress);
@@ -177,6 +517,12 @@ const topLinks = [
document.addEventListener('astro:page-load', () => { document.addEventListener('astro:page-load', () => {
enhanceSidebarGroupLinks(); enhanceSidebarGroupLinks();
sanitizeNavLabels();
sanitizeDocHeadings();
decorateSectionIcons();
annotateLinkDestinations();
bindCopyIpChips();
bindCraftCatalogFilters();
setReadProgress(); setReadProgress();
}); });
</script> </script>
@@ -203,10 +549,70 @@ const topLinks = [
padding: 0.25rem; padding: 0.25rem;
margin: -0.25rem; margin: -0.25rem;
min-width: 0; min-width: 0;
gap: 1rem; gap: 1.1rem;
align-items: center; align-items: center;
} }
.wiki-brand {
display: inline-flex;
align-items: center;
gap: 0.55rem;
text-decoration: none;
flex-shrink: 0;
border: 1px solid transparent;
border-radius: 0.3rem;
padding: 0.2rem 0.28rem 0.2rem 0.22rem;
transition: border-color 150ms ease, background 150ms ease;
}
.wiki-brand:hover {
border-color: color-mix(in srgb, var(--sl-color-accent) 32%, transparent);
background: color-mix(in srgb, var(--sl-color-accent-low) 64%, transparent);
}
.wiki-brand__icon {
width: 1.85rem;
height: 1.85rem;
display: inline-flex;
align-items: center;
justify-content: center;
border: 0;
background: transparent;
box-shadow: none;
}
.wiki-brand__icon img {
width: 100%;
height: 100%;
display: block;
border-radius: 0;
object-fit: contain;
}
.wiki-brand__copy {
display: inline-flex;
flex-direction: column;
align-items: flex-start;
line-height: 1;
}
.wiki-brand__title {
font-family: 'Sora', sans-serif;
font-size: 1.43rem;
font-weight: 700;
letter-spacing: 0.02em;
color: var(--sl-color-white);
}
.wiki-brand__subtitle {
margin-top: 0.14rem;
font-family: 'Sora', sans-serif;
font-size: 0.56rem;
font-weight: 700;
letter-spacing: 0.28em;
color: var(--sl-color-gray-3);
}
.wiki-top-nav { .wiki-top-nav {
display: none; display: none;
gap: 0.45rem; gap: 0.45rem;
@@ -327,51 +733,56 @@ const topLinks = [
.wiki-back-to-top { .wiki-back-to-top {
position: fixed; position: fixed;
top: auto; top: auto;
right: max(0.75rem, env(safe-area-inset-right)); right: max(1.35rem, calc(env(safe-area-inset-right) + 0.8rem));
bottom: max(1.1rem, env(safe-area-inset-bottom)); bottom: max(1.45rem, calc(env(safe-area-inset-bottom) + 0.7rem));
z-index: 30; z-index: 30;
border: 1px solid color-mix(in srgb, var(--sl-color-accent) 70%, transparent); border: 1px solid color-mix(in srgb, var(--sl-color-accent) 74%, transparent);
border-radius: 999px; border-radius: 999px;
background: linear-gradient( background: linear-gradient(
140deg, 140deg,
color-mix(in srgb, var(--wiki-purple-2) 78%, #101522), color-mix(in srgb, var(--wiki-purple-2) 74%, #101522),
color-mix(in srgb, var(--wiki-blue-2) 82%, #101522) color-mix(in srgb, var(--wiki-blue-2) 84%, #101522)
); );
color: #f6f9ff; color: #f6f9ff;
font-family: 'Sora', sans-serif; width: 3.1rem;
font-size: 1.1rem; height: 3.1rem;
font-weight: 600;
letter-spacing: 0.01em;
width: 2.6rem;
height: 2.6rem;
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
padding: 0; padding: 0;
line-height: 1;
box-shadow: box-shadow:
0 10px 24px hsl(220 95% 62% / 0.24), 0 0 0 1px hsl(214 88% 70% / 0.24),
0 0 0 1px hsl(214 88% 70% / 0.22); 0 0 24px hsl(217 100% 68% / 0.38),
0 0 42px hsl(221 100% 65% / 0.22);
opacity: 0; opacity: 0;
visibility: hidden; visibility: hidden;
transform: translateY(6px); transform: translateY(8px) scale(0.96);
pointer-events: none; pointer-events: none;
transition: opacity 160ms ease, transform 160ms ease, border-color 160ms ease; transition: opacity 180ms ease, transform 180ms ease, border-color 180ms ease, box-shadow 180ms ease;
}
.wiki-back-to-top__icon {
width: 1.5rem;
height: 1.5rem;
stroke: currentColor;
stroke-width: 2.15;
stroke-linecap: round;
stroke-linejoin: round;
} }
.wiki-back-to-top.is-visible { .wiki-back-to-top.is-visible {
opacity: 1; opacity: 1;
visibility: visible; visibility: visible;
transform: translateY(0); transform: translateY(0) scale(1);
pointer-events: auto; pointer-events: auto;
} }
.wiki-back-to-top:hover { .wiki-back-to-top:hover {
border-color: color-mix(in srgb, #9ec4ff 80%, transparent); border-color: color-mix(in srgb, #9ec4ff 80%, transparent);
box-shadow: box-shadow:
0 14px 28px hsl(220 95% 62% / 0.32),
0 0 0 1px hsl(214 88% 70% / 0.35), 0 0 0 1px hsl(214 88% 70% / 0.35),
0 0 18px hsl(220 96% 68% / 0.34); 0 0 28px hsl(219 97% 70% / 0.44),
0 0 50px hsl(221 98% 68% / 0.27);
} }
.social-icons::after { .social-icons::after {
@@ -415,12 +826,36 @@ const topLinks = [
} }
@media (max-width: 50rem) { @media (max-width: 50rem) {
.wiki-brand {
padding: 0.14rem 0.2rem;
gap: 0.42rem;
}
.wiki-brand__icon {
width: 1.55rem;
height: 1.55rem;
}
.wiki-brand__title {
font-size: 1.08rem;
}
.wiki-brand__subtitle {
font-size: 0.46rem;
letter-spacing: 0.24em;
}
.wiki-back-to-top { .wiki-back-to-top {
top: auto; top: auto;
right: max(0.62rem, env(safe-area-inset-right)); right: max(1rem, calc(env(safe-area-inset-right) + 0.52rem));
bottom: max(1rem, env(safe-area-inset-bottom)); bottom: max(1.18rem, calc(env(safe-area-inset-bottom) + 0.58rem));
width: 2.5rem; width: 2.85rem;
height: 2.5rem; height: 2.85rem;
}
.wiki-back-to-top__icon {
width: 1.34rem;
height: 1.34rem;
} }
} }
} }

View File

@@ -5,7 +5,7 @@ description: "Концепция мира, формат сервера и осн
## Концепция ## Концепция
Сервер построен вокруг идеи «архива реальностей»: каждая локация выглядит как отдельный фрагмент мира со своей физикой и историей. Сервер построен как единый живой мир: у разных локаций свой стиль, история и атмосфера.
### Формат ### Формат
@@ -13,14 +13,6 @@ description: "Концепция мира, формат сервера и осн
- Выживание с RPG-элементами - Выживание с RPG-элементами
- Упор на исследование и кооператив - Упор на исследование и кооператив
## Лор в двух словах
После Раскола Неба мир разделился на слои. Игроки находят обломки карт, восстанавливают порталы и открывают утраченные ремёсла.
:::caution
Некоторые сюжетные зоны открываются только после выполнения цепочки квестов.
:::
## Техническая база ## Техническая база
| Параметр | Значение | | Параметр | Значение |
@@ -31,7 +23,7 @@ description: "Концепция мира, формат сервера и осн
<div class="see-also"> <div class="see-also">
<p>Смотри также</p> <p>Смотри также</p>
<a href="/mechanics/">Механики</a> · <a href="/team/">Команда проекта</a> <a href="/general/">Общее</a> · <a href="/faq/">FAQ</a>
</div> </div>

View File

@@ -50,11 +50,11 @@ description: "Полное руководство по ферментации,
Всего существует 10 уровней качества: Всего существует 10 уровней качества:
- `` — уровень 1 - `I` — уровень 1
- `` — уровень 2 - `II` — уровень 2
- `★☆` — уровень 3 - `III` — уровень 3
- `...` - `...`
- `★★★★★ (10)` — максимальное качество - `X` — максимальное качество (уровень 10)
:::note :::note
Чем точнее соблюдён рецепт, тем выше качество. Чем точнее соблюдён рецепт, тем выше качество.

View File

@@ -1,19 +0,0 @@
---
title: "Алкоголь"
description: "Переход к подразделам алкогольной системы."
---
## Подразделы
Выберите нужный раздел:
<div class="lore-grid alcohol-nav-grid">
<a class="lore-card alcohol-nav-card" href="/alcohol-brewing/">
<h3>Как варить</h3>
<p>Ферментация, бочки, качество напитков, алкогольность и эффекты.</p>
</a>
<a class="lore-card alcohol-nav-card" href="/alcohol-recipes/">
<h3>Рецепты напитков</h3>
<p>Полный список рецептов, ингредиентов и параметров приготовления.</p>
</a>
</div>

View File

@@ -3,15 +3,52 @@ title: "Все IP"
description: "Адреса и порты сервера PARABOX для Java и Bedrock." description: "Адреса и порты сервера PARABOX для Java и Bedrock."
--- ---
## 🎮 Основное ## Основные адреса
### Java `1.21.11` <div class="ip-main-grid">
<article class="ip-main-card">
<h3>Java 1.21.11</h3>
<ul>
<li>
Основной:
<button class="copy-ip-chip" type="button" data-copy-ip="mc.parabox.su" aria-label="Скопировать: mc.parabox.su">
<code>mc.parabox.su</code>
</button>
</li>
<li>
AnyCast-прокси:
<button class="copy-ip-chip" type="button" data-copy-ip="mine.rpcm.su" aria-label="Скопировать: mine.rpcm.su">
<code>mine.rpcm.su</code>
</button>
</li>
</ul>
</article>
- Основной: `mc.rpcm.su` <article class="ip-main-card">
- AnyCast-прокси: `mine.rpcm.su` <h3>Bedrock 26.2</h3>
<ul>
<li>
Основной:
<button class="copy-ip-chip" type="button" data-copy-ip="mc.parabox.su" aria-label="Скопировать: mc.parabox.su">
<code>mc.parabox.su</code>
</button>
</li>
<li>
Запасной IP:
<button class="copy-ip-chip" type="button" data-copy-ip="213.152.43.52" aria-label="Скопировать: 213.152.43.52">
<code>213.152.43.52</code>
</button>
</li>
<li>
Порт:
<button class="copy-ip-chip" type="button" data-copy-ip="25875" aria-label="Скопировать: 25875">
<code>25875</code>
</button>
</li>
</ul>
</article>
</div>
### Bedrock `26.2` <div class="ip-main-note">
Используйте запасной адрес, если основной IP временно недоступен.
- Основной: `mc.rpcm.su` </div>
- Запаска: `213.152.43.52`
- Порт: `25875`

View File

@@ -3,26 +3,26 @@ title: "Города"
description: "Раздел для представления городов и проектов игроков." description: "Раздел для представления городов и проектов игроков."
--- ---
## 🏠 Города и проекты игроков ## Города и проекты игроков
На **PARABOX** вы можете создать свой город у нас на проекте, собрать жителей и развивать свою территорию. На PARABOX можно создать свой город, собрать жителей и развивать территорию вместе с другими игроками.
<div class="lore-grid"> <div class="lore-grid">
<article class="lore-card city-feature-card"> <article class="lore-card city-feature-card">
<p><strong class="city-highlight">Представить свой город.</strong> Расскажите о своём проекте и покажите, чем он уникален.</p> <p><strong class="city-highlight">Представить свой город.</strong> Расскажите о проекте и его отличительных чертах.</p>
</article> </article>
<article class="lore-card city-feature-card"> <article class="lore-card city-feature-card">
<p><strong class="city-highlight">Искать жителей.</strong> Находите игроков, которые хотят вступить в ваш город.</p> <p><strong class="city-highlight">Найти жителей.</strong> Публикуйте набор и указывайте роли, которые сейчас нужны городу.</p>
</article> </article>
<article class="lore-card city-feature-card"> <article class="lore-card city-feature-card">
<p><strong class="city-highlight">Показывать постройки.</strong> Делитесь скриншотами и прогрессом развития территории.</p> <p><strong class="city-highlight">Показывать развитие.</strong> Делитесь скриншотами, координатами и текущими задачами.</p>
</article> </article>
<article class="lore-card city-feature-card"> <article class="lore-card city-feature-card">
<p><strong class="city-highlight">Организовывать совместные проекты.</strong> Договаривайтесь о союзах, ивентах и общих инициативах.</p> <p><strong class="city-highlight">Организовывать союзы.</strong> Договаривайтесь о торговле, ивентах и совместных проектах.</p>
</article> </article>
</div> </div>
## 📌 Если создаёте пост о городе ## Шаблон публикации города
```text ```text
Название города: Название города:
@@ -33,8 +33,8 @@ description: "Раздел для представления городов и
Правила города: Правила города:
``` ```
Это поможет другим игрокам быстрее к вам присоединиться. Подробный процесс входа на сервер описан в статье <a href="/getting-started/">«Начало игры»</a>.
:::tip :::tip
Чем понятнее и полнее пост, тем быстрее игроки смогут найти и выбрать ваш город. Чем понятнее и полнее описание города, тем быстрее к вам присоединятся игроки.
::: :::

View File

@@ -1,14 +1,82 @@
--- ---
title: "Команды" title: "Команды"
description: "Черновик страницы с командами сервера." description: "Справочник игровых команд: чат, личные сообщения, RP и полезные функции."
--- ---
## Команды ## Команды
Это временная страница-заглушка. Ниже собраны основные команды сервера, сгруппированные по категориям.
- `/spawn` — пример команды 1 ### Настройки
- `/home` — пример команды 2
- `/rtp` — пример команды 3
Позже замените этот список на реальные команды вашего сервера. - `/chatsetting` - открыть меню настроек чата (уведомления, отображение, звук и т.д.).
### Личные сообщения
- `/tell <ник> <сообщение>` - отправить личное сообщение игроку.
- `/msg`, `/w`, `/m`, `/message`, `/send` - альтернативы команды `/tell`.
- `/r` - ответить последнему игроку.
### Игнор
- `/ignore <ник>` - игнорировать сообщения игрока.
### Развлечения
- `/ball <вопрос>` - задать вопрос и получить случайный ответ.
- `/tictactoe <ник>` - сыграть в крестики-нолики.
- `/rockpaperscissors <ник>` - камень-ножницы-бумага.
- `/try` - проверить удачу (случайный шанс).
- `/coin` - подбросить монетку.
- `/dice` - бросить кубик.
### Кастомные пластинки
- `/disc burn <url> [name]` - создать кастомную пластинку из аудио по URL.
- `/disc erase` - вернуть кастомную пластинку к обычному виду.
- `/disc search <query>` - найти треки на YouTube.
:::note
Для `/disc burn` нужно держать музыкальную пластинку в руке.
:::
### RP и взаимодействие
- `/do <действие>` - RP-описание действия от третьего лица.
- `/anon <сообщение>` - отправить анонимное сообщение.
- `/helper` - попросить помощь.
### Статус игрока
- `/afk` - включить или выключить режим AFK.
- `/crawl` - позволяет игроку ползти.
- `/sit` - позволяет игроку сидеть.
- `/lay` - позволяет игроку лечь.
### ImageFrame (изображения на картах)
- `/imageframe select` - выбрать рамки, в которые будет поставлено изображение.
- `/imageframe create <name> <url> <width> <height>` - создать новое изображение на картах.
- `/imageframe create <name> <url> selection` - создать изображение и сразу разместить его в выбранных рамках.
- `/imageframe get <name>` - получить ранее созданное вами изображение.
- `/imageframe get <name> selection` - поставить ранее созданное изображение сразу в выбранные рамки.
- `/imageframe list` - показать список ваших созданных изображений.
- `/imageframe info` - показать информацию об изображении, которое вы держите в руке.
- `/imageframe refresh [image_name] [new_url]` - обновить изображение из источника (при необходимости с новой ссылкой).
- `/imageframe rename <name> <new_name>` - переименовать ваше изображение.
- `/imageframe delete <name>` - удалить ваше изображение.
:::note
Для `/imageframe create` используйте прямую ссылку на изображение.
`<width>` и `<height>` - это размер в картах (например `2 2` для сетки 2x2).
:::
### Информация
- `/ping` - узнать задержку (пинг).
- `/toponline` - посмотреть топ игроков по наигранному времени.
- `/breweryx info` - показать уровень опьянения.
### Символы
- `/symbol` - открыть меню символов.

View File

@@ -0,0 +1,155 @@
---
title: "Крафты"
description: "Раздел по кастомным крафтам сервера PARABOX."
---
## Каталог крафтов
<div class="craft-catalog" data-craft-catalog>
<div class="craft-controls">
<label class="craft-search-field" for="craft-search-input">
<span>Поиск по названию</span>
<input
id="craft-search-input"
class="craft-search-input"
type="search"
placeholder="Например, наковальня или книга"
data-craft-search
/>
</label>
<div class="craft-filter-group" role="group" aria-label="Фильтр крафтов по категориям">
<button type="button" class="craft-filter-chip is-active" data-craft-filter="all" aria-pressed="true">Все</button>
<button type="button" class="craft-filter-chip" data-craft-filter="special" aria-pressed="false">Спец-предметы</button>
<button type="button" class="craft-filter-chip" data-craft-filter="blocks" aria-pressed="false">Блоки и станции</button>
<button type="button" class="craft-filter-chip" data-craft-filter="smelting" aria-pressed="false">Переработка</button>
</div>
</div>
<p class="craft-empty" data-craft-empty hidden>По вашему запросу крафты не найдены.</p>
<section class="craft-group" data-craft-group data-craft-category="special">
<h3>Спец-предметы</h3>
<div class="craft-grid">
<article class="lore-card craft-card" data-craft-item data-craft-category="special" data-craft-name="невидимая рамка">
<h3>Невидимая рамка</h3>
<img class="craft-card-image" src="/crafts/invisible-item-frame.png" alt="Рецепт невидимой рамки" loading="lazy" />
</article>
<article class="lore-card craft-card" data-craft-item data-craft-category="special" data-craft-name="невидимая светящаяся рамка">
<h3>Невидимая светящаяся рамка</h3>
<img class="craft-card-image" src="/crafts/invisible-glow-item-frame.png" alt="Рецепт невидимой светящейся рамки" loading="lazy" />
</article>
<article class="lore-card craft-card" data-craft-item data-craft-category="special" data-craft-name="невидимый свет">
<h3>Невидимый свет</h3>
<img class="craft-card-image" src="/crafts/invisible-light.png" alt="Рецепт невидимого света" loading="lazy" />
</article>
<article class="lore-card craft-card" data-craft-item data-craft-category="special" data-craft-name="чародейская книга">
<h3>Чародейская книга</h3>
<img class="craft-card-image" src="/crafts/enchanted-book.png" alt="Рецепт чародейской книги" loading="lazy" />
</article>
<article class="lore-card craft-card" data-craft-item data-craft-category="special" data-craft-name="книга знаний">
<h3>Книга знаний</h3>
<img class="craft-card-image" src="/crafts/knowledge-book.png" alt="Рецепт книги знаний" loading="lazy" />
</article>
<article class="lore-card craft-card" data-craft-item data-craft-category="special" data-craft-name="дыхание дракона">
<h3>Дыхание дракона</h3>
<img class="craft-card-image" src="/crafts/dragons-breath.png" alt="Рецепт дыхания дракона" loading="lazy" />
</article>
<article class="lore-card craft-card" data-craft-item data-craft-category="special" data-craft-name="светящиеся чернила">
<h3>Светящиеся чернила</h3>
<img class="craft-card-image" src="/crafts/glow-ink-sac.png" alt="Рецепт светящихся чернил" loading="lazy" />
</article>
<article class="lore-card craft-card" data-craft-item data-craft-category="special" data-craft-name="мембрана фантома">
<h3>Мембрана фантома</h3>
<img class="craft-card-image" src="/crafts/phantom-membrane.png" alt="Рецепт мембраны фантома" loading="lazy" />
</article>
<article class="lore-card craft-card" data-craft-item data-craft-category="special" data-craft-name="бирка">
<h3>Бирка</h3>
<img class="craft-card-image" src="/crafts/name-tag.png" alt="Рецепт бирки" loading="lazy" />
</article>
<article class="lore-card craft-card" data-craft-item data-craft-category="special" data-craft-name="мешок">
<h3>Мешок</h3>
<img class="craft-card-image" src="/crafts/bundle.png" alt="Рецепт мешка" loading="lazy" />
</article>
</div>
</section>
<section class="craft-group" data-craft-group data-craft-category="blocks">
<h3>Блоки и рабочие станции</h3>
<div class="craft-grid">
<article class="lore-card craft-card" data-craft-item data-craft-category="blocks" data-craft-name="стол лучника">
<h3>Стол лучника</h3>
<img class="craft-card-image" src="/crafts/fletching-table.png" alt="Рецепт стола лучника" loading="lazy" />
</article>
<article class="lore-card craft-card" data-craft-item data-craft-category="blocks" data-craft-name="стол картографа">
<h3>Стол картографа</h3>
<img class="craft-card-image" src="/crafts/cartography-table.png" alt="Рецепт стола картографа" loading="lazy" />
</article>
<article class="lore-card craft-card" data-craft-item data-craft-category="blocks" data-craft-name="ткацкий станок">
<h3>Ткацкий станок</h3>
<img class="craft-card-image" src="/crafts/loom.png" alt="Рецепт ткацкого станка" loading="lazy" />
</article>
<article class="lore-card craft-card" data-craft-item data-craft-category="blocks" data-craft-name="нотный блок">
<h3>Нотный блок</h3>
<img class="craft-card-image" src="/crafts/note-block.png" alt="Рецепт нотного блока" loading="lazy" />
</article>
<article class="lore-card craft-card" data-craft-item data-craft-category="blocks" data-craft-name="проигрыватель">
<h3>Проигрыватель</h3>
<img class="craft-card-image" src="/crafts/jukebox.png" alt="Рецепт проигрывателя" loading="lazy" />
</article>
<article class="lore-card craft-card" data-craft-item data-craft-category="blocks" data-craft-name="раздатчик">
<h3>Раздатчик</h3>
<img class="craft-card-image" src="/crafts/dispenser.png" alt="Рецепт раздатчика" loading="lazy" />
</article>
<article class="lore-card craft-card" data-craft-item data-craft-category="blocks" data-craft-name="колокол">
<h3>Колокол</h3>
<img class="craft-card-image" src="/crafts/bell.png" alt="Рецепт колокола" loading="lazy" />
</article>
<article class="lore-card craft-card" data-craft-item data-craft-category="blocks" data-craft-name="обтесанное бревно">
<h3>Обтесанное бревно</h3>
<img class="craft-card-image" src="/crafts/stripped-log-stonecutter.png" alt="Рецепт обтесанного бревна в камнерезе" loading="lazy" />
</article>
<article class="lore-card craft-card" data-craft-item data-craft-category="blocks" data-craft-name="прочный полублок">
<h3>Прочный полублок</h3>
<img class="craft-card-image" src="/crafts/sturdy-slab.png" alt="Рецепт прочного полублока" loading="lazy" />
</article>
<article class="lore-card craft-card" data-craft-item data-craft-category="blocks" data-craft-name="наковальня вариант 1">
<h3>Наковальня (вариант 1)</h3>
<img class="craft-card-image" src="/crafts/anvil-variant-base.png" alt="Первый вариант рецепта наковальни" loading="lazy" />
</article>
<article class="lore-card craft-card" data-craft-item data-craft-category="blocks" data-craft-name="наковальня вариант 2">
<h3>Наковальня (вариант 2)</h3>
<img class="craft-card-image" src="/crafts/anvil-variant-l.png" alt="Второй вариант рецепта наковальни" loading="lazy" />
</article>
</div>
</section>
<section class="craft-group" data-craft-group data-craft-category="smelting">
<h3>Переработка и конверсия</h3>
<div class="craft-grid">
<article class="lore-card craft-card" data-craft-item data-craft-category="smelting" data-craft-name="компас из компаса восстановления">
<h3>Компас из компаса восстановления</h3>
<img class="craft-card-image" src="/crafts/recovery-compass-to-compass-smelting.png" alt="Переплавка компаса восстановления в обычный компас" loading="lazy" />
</article>
<article class="lore-card craft-card" data-craft-item data-craft-category="smelting" data-craft-name="железный слиток из компаса">
<h3>Железный слиток из компаса</h3>
<img class="craft-card-image" src="/crafts/compass-to-iron-ingot-smelting.png" alt="Переплавка компаса в железный слиток" loading="lazy" />
</article>
<article class="lore-card craft-card" data-craft-item data-craft-category="smelting" data-craft-name="золотой слиток из часов">
<h3>Золотой слиток из часов</h3>
<img class="craft-card-image" src="/crafts/clock-to-gold-ingot-smelting.png" alt="Переплавка часов в золотой слиток" loading="lazy" />
</article>
<article class="lore-card craft-card" data-craft-item data-craft-category="smelting" data-craft-name="красное стекло">
<h3>Красное стекло</h3>
<img class="craft-card-image" src="/crafts/red-glass-smelting.png" alt="Переплавка в красное стекло" loading="lazy" />
</article>
<article class="lore-card craft-card" data-craft-item data-craft-category="smelting" data-craft-name="алмазная руда вариант 1">
<h3>Алмазная руда (вариант 1)</h3>
<img class="craft-card-image" src="/crafts/diamond-ore-variant-k.png" alt="Первый вариант рецепта алмазной руды" loading="lazy" />
</article>
<article class="lore-card craft-card" data-craft-item data-craft-category="smelting" data-craft-name="алмазная руда вариант 2">
<h3>Алмазная руда (вариант 2)</h3>
<img class="craft-card-image" src="/crafts/diamond-ore-variant-s.png" alt="Второй вариант рецепта алмазной руды" loading="lazy" />
</article>
</div>
</section>
</div>

View File

@@ -1,33 +0,0 @@
---
title: "Донат / привилегии"
description: "Добровольная поддержка сервера, наборы и прозрачные правила привилегий."
---
## Принципы
- Донат не должен ломать баланс мира.
- Боевые преимущества ограничены и прозрачны.
- Все пакеты имеют чёткое описание.
## Уровни поддержки
| Уровень | Что входит |
| --- | --- |
| Traveler | Косметика + расширенный /home |
| Patron | Больше слотов хранилища + титул |
| Curator | Эксклюзивные визуальные эффекты |
## Политика возвратов
Возвраты рассматриваются через тикет-систему в течение 7 дней после покупки.
:::note
Покупка привилегий - способ поддержать развитие сервера, а не обязательное условие комфортной игры.
:::
<div class="see-also">
<p>Смотри также</p>
<a href="/rules/">Правила</a> · <a href="/contacts/">Контакты / ссылки</a>
</div>

View File

@@ -1,38 +0,0 @@
---
title: "Экономика"
description: "Валюты, рынки, аукцион, контракты и рекомендации по торговле."
---
## Валюты
- `Aurum` - базовая торговая валюта.
- `Echo` - редкая валютная единица для реликвий.
## Как работает рынок
### Аукцион
Игроки выставляют предметы на открытый рынок.
### Контракты
Сделки между игроками с фиксированными условиями.
## Мини-стратегия для старта
| Шаг | Действие | Ожидаемый эффект |
| --- | --- | --- |
| 1 | Продавать излишки еды | Быстрый стартовый капитал |
| 2 | Копить железо и редстоун | Стабильный спрос |
| 3 | Вкладываться в алхимию | Высокая маржа |
:::caution
Не держи все активы в одном виде ресурса: цены цикличны.
:::
<div class="see-also">
<p>Смотри также</p>
<a href="/items-resources/">Предметы и ресурсы</a> · <a href="/donate/">Донат / привилегии</a>
</div>

View File

@@ -1,64 +0,0 @@
---
title: "Как редактировать wiki"
description: "Простая инструкция по добавлению и изменению страниц в Markdown."
---
## Быстрый принцип
Каждая статья - отдельный `.md`-файл в `src/content/docs/`.
## Минимальный frontmatter
```yaml
---
title: "Название страницы"
description: "Короткое описание страницы"
---
```
## Как добавить новую страницу
1. Создай файл в `src/content/docs/`, например `new-biome.md`.
2. Добавь frontmatter (`title`, `description`).
3. Напиши контент в Markdown (заголовки, списки, таблицы, код).
4. Добавь ссылку в `sidebar` в `astro.config.mjs`.
## Полезные блоки Starlight
```md
:::note
Заметка
:::
:::tip
Подсказка
:::
:::caution
Предупреждение
:::
:::danger
Опасность
:::
```
## Пример spoiler/details
```md
<details>
<summary>Показать секрет</summary>
Здесь скрытый текст.
</details>
```
## Где редактируется меню
Меню и порядок разделов настраиваются в `astro.config.mjs` -> `starlight({ sidebar: [...] })`.
<div class="see-also">
<p>Смотри также</p>
<a href="/templates/new-page-template/">Шаблон новой страницы</a>
</div>

View File

@@ -3,16 +3,59 @@ title: "Общее"
description: "Общая информация и веб-карта сервера PARABOX." description: "Общая информация и веб-карта сервера PARABOX."
--- ---
## Общее ## Веб-карта сервера
На сервере доступна интерактивная веб-карта, где можно смотреть мир в реальном времени: Интерактивная веб-карта отображает мир в реальном времени и помогает быстро ориентироваться на сервере.
- города и постройки игроков; На карте вы увидите:
- дороги и основные локации;
- общий масштаб мира и ориентиры для навигации.
<div class="map-cta-wrap"> - расположение городов и построек игроков;
- дороги, биомы и основные локации;
- масштаб карты.
<div class="map-actions">
<a class="map-cta-button" href="https://map.rpcm.su/#world:0:0:0:1500:0:0:0:0:perspective" target="_blank" rel="noopener noreferrer"> <a class="map-cta-button" href="https://map.rpcm.su/#world:0:0:0:1500:0:0:0:0:perspective" target="_blank" rel="noopener noreferrer">
Открыть веб-карту сервера Открыть веб-карту
</a> </a>
</div> </div>
---
## Как сменить скин
На сервере доступна система скинов, которая позволяет установить любой внешний вид. Скин будет отображаться в чате, на карте и в других местах.
### Способ 1. Через команду
- для установки: `/skin set <ссылка на скин / ник лицензионного аккаунта>`
- для сброса: `/skin clear`
### Способ 2. Через сайт SkinRestorer
1. Загрузите скин файлом на сайт: [SkinRestorer](https://skinsrestorer.net/upload)
2. Нажмите кнопку `GENERATE` и скопируйте полученную команду.
3. Введите команду в чате Minecraft.
---
## ImageForm (бета): гайд
`ImageForm` позволяет делать map-art автоматически по ссылке на изображение, без ручной постройки пиксель-арт схем.
### Как использовать
1. Подготовьте прямую ссылку на картинку (форматы `png`/`jpg`/`webp`).
2. Зайдите на сервер и вызовите инструмент ImageForm (команда/интерфейс, доступный на вашей роли).
3. Вставьте ссылку на изображение и подтвердите создание.
4. Выберите размер и формат карты (если сервер предложит параметры).
5. Дождитесь генерации и заберите готовый результат.
### Советы по качеству
- используйте изображения с хорошим контрастом и без мелкого текста;
- лучше всего подходят квадратные или близкие к квадрату картинки;
- при необходимости уменьшите изображение заранее, чтобы карта читалась лучше.
:::note
ImageForm работает в бета-режиме: отдельные параметры или ограничения могут меняться в следующих патчах.
:::

View File

@@ -3,10 +3,10 @@ title: "Начало игры"
description: "Как подать заявку на сервер PARABOX и что указать в анкете." description: "Как подать заявку на сервер PARABOX и что указать в анкете."
--- ---
## ✏️ Захотелось к нам? ## Как вступить
Чтобы попасть на сервер, необходимо отправить запрос через нашего бота. Чтобы попасть на сервер, отправьте заявку через бота.
После одобрения вы получите доступ и окунётесь в удивительные миры **PARABOX**. После одобрения вы получите доступ к миру PARABOX.
<div class="see-also"> <div class="see-also">
<p>Подача заявки через бота</p> <p>Подача заявки через бота</p>
@@ -15,8 +15,8 @@ description: "Как подать заявку на сервер PARABOX и чт
## Форма анкеты ## Форма анкеты
Чтобы вступить к нам, просим заполнить небольшую анкету в боте: Чтобы вступить, заполните короткую анкету в боте:
1. Как к вам обращаться? Укажите ваш псевдоним или имя. 1. Как к вам обращаться (имя или псевдоним).
2. Ваш никнейм, который будет привязан к серверу. 2. Ваш никнейм для привязки к серверу.
3. От какого проекта вы? Если не от проекта, укажите, от кого вы узнали о сервере. 3. От какого проекта вы пришли, или откуда узнали о сервере.

View File

@@ -1,50 +0,0 @@
---
title: "Гайды"
description: "Практические сценарии: выживание, прогресс, босс-раны и командная игра."
---
## Навигатор по гайдам
<div class="lore-grid">
<article class="lore-card">
<h3>Соло-старт</h3>
<p>Как стабильно развиться одному игроку за первые два вечера.</p>
</article>
<article class="lore-card">
<h3>Гильдейский старт</h3>
<p>Роли в группе, распределение ресурсов и ротация задач.</p>
</article>
<article class="lore-card">
<h3>Босс-раны</h3>
<p>Минимальный набор, тактики и контроль рисков на арене.</p>
</article>
</div>
## Пример структурированного гайда
### Подготовка
- 32+ еды
- Броня не ниже железной
- 2 тотема или 3 зелья лечения
### Выполнение
1. Активируй обелиск.
2. Удерживай центральную платформу 3 волны.
3. Сфокусируй урон по призывателю на 4-й фазе.
### Завершение
Разбери добычу по ролям: танк, саппорт, дамагер.
:::danger
Не заходи в событие с поломанной бронёй: штраф на урон и критический риск потери лута.
:::
<div class="see-also">
<p>Смотри также</p>
<a href="/mechanics/">Механики</a> · <a href="/professions/">Профессии / классы / расы</a>
</div>

View File

@@ -2,46 +2,40 @@
title: "Project PARABOX" title: "Project PARABOX"
description: "Единый сервер РПКМ: города проектов, экономика, выживание и взаимодействие между игроками." description: "Единый сервер РПКМ: города проектов, экономика, выживание и взаимодействие между игроками."
hero: hero:
tagline: Единый мир для проектов РПКМ и игроков tagline: Единый мир для проектов и игроков
actions: actions:
- text: Начать игру - text: Начать игру
link: /getting-started/ link: /getting-started/
icon: right-arrow icon: right-arrow
variant: primary variant: primary
- text: Читать сюжет - text: Смотреть все IP
link: /story/ link: /all-ip/
variant: minimal variant: minimal
--- ---
## Project PARABOX ## Project PARABOX
Мы запускаем единый сервер, где каждый проект РПКМ может создать свой собственный город, а игроки могут наслаждаться выживанием, экономикой и взаимодействием между городами. Project PARABOX объединяет проекты РПКМ и игроков в едином живом мире: выживание, развитие городов, торговля и совместные события происходят на одной карте.
## Что вас ждёт ## Города, регистрация и первые шаги
- Система городов. Если у вас есть проект в РПКМ, вы можете создать свой город, собрать жителей и развивать собственную территорию. 1. Подайте заявку через бота и дождитесь подтверждения.
2. Зайдите на сервер по одному из IP выше.
3. Зарегистрируйтесь или войдите в игровую систему.
4. Выберите город для вступления или создайте свой проектный город.
5. Ознакомьтесь с правилами и базовыми механиками.
Подробный разбор процесса вступления находится в статье <a href="/getting-started/">«Начало игры»</a>, а информация по городам — в разделе <a href="/cities/">«Города»</a>.
## Основные особенности
- Система городов с возможностью набора жителей.
- Экономика и торговля между игроками. - Экономика и торговля между игроками.
- Общий мир для всех проектов ЛРПКМ.
- Ивенты и активности. - Ивенты и активности.
- Классическое выживание с социальным взаимодействием. - Классическое выживание с социальным взаимодействием.
- И просто весёлое времяпровождение.
:::tip :::tip
Project PARABOX объединяет проекты и игроков в одном живом мире, где каждый может выбрать свой формат игры: развитие города, торговлю, выживание или участие в событиях. Чем быстрее вы подключитесь по IP и выберете точку старта, тем проще будет влиться в текущие города и события.
::: :::
## ❓ Основные особенности ## Добро пожаловать и приятной игры
- Система городов.
- Экономика / торговля.
- Ивенты и активности.
## 🚀 Как начать играть
1. Подайте заявку.
2. Зайдите на сервер по IP.
3. Прочитайте правила в соответствующем разделе.
4. Зарегистрируйтесь или войдите в систему.
5. Найдите город или создайте свой.
## ✨ Добро пожаловать и приятной игры!

View File

@@ -1,42 +0,0 @@
---
title: "Предметы и ресурсы"
description: "Каталог ключевых материалов, редких артефактов и их применение."
---
## Базовые ресурсы
- Древесина
- Камень
- Железо
- Кварц
## Редкие материалы
### Пыль кометы
Используется для усиления портальных якорей.
### Лунный обсидиан
Нужен для защитных печатей и высокоуровневых рецептов.
## Пример блока внимания
:::danger
Артефакты с меткой «Связанный» нельзя передавать или продавать.
:::
## Таблица предметов
| Предмет | Где найти | Для чего нужен |
| --- | --- | --- |
| Пыль кометы | Небесный дождь | Ритуалы усиления |
| Лунный обсидиан | Глубинные разломы | Структуры защиты |
| Эхо-кристалл | Рейдовые боссы | Улучшение реликвий |
<div class="see-also">
<p>Смотри также</p>
<a href="/mechanics/">Механики</a> · <a href="/guides/">Гайды</a>
</div>

View File

@@ -1,41 +0,0 @@
---
title: "Механики"
description: "Основные игровые системы: энергия, климат, аномалии и мировые события."
---
## Энергия эфира
Эфир усиливает способности и влияет на доступ к скрытым зонам.
| Уровень эфира | Эффект |
| --- | --- |
| 0-20 | Базовые действия |
| 21-60 | Бонус к добыче и скорости |
| 61+ | Открываются артефактные узлы |
### Как повышать эфир
- Выполнять ежедневные контракты.
- Закрывать аномалии в группе.
- Исследовать архивные башни.
## Мировые события
### Разломы
Появляются раз в несколько часов и требуют командной обороны.
### Небесный дождь
Даёт редкие ингредиенты, но привлекает элитных мобов.
:::note
`h2` и `h3` автоматически попадают в оглавление страницы справа.
:::
<div class="see-also">
<p>Смотри также</p>
<a href="/items-resources/">Предметы и ресурсы</a> · <a href="/rules/">Правила</a>
</div>

View File

@@ -1,42 +0,0 @@
---
title: "Профессии / классы / расы"
description: "Гибкая RPG-система: роли, бонусы, ограничения и синергия в группе."
---
## Расы
- Астралы: бонус к мане и исследованию.
- Форджеры: ускоренный крафт и переработка руд.
- Вейлборны: скрытность и мобильность.
## Классы
### Страж
Высокая выживаемость и контроль зоны.
### Проводник
Баффы команды и лечение в бою.
### Пилигрим
Урон по одиночным целям и ускорение перемещения.
## Профессии
1. Алхимик
2. Инженер
3. Хранитель ферм
4. Архивариус-торговец
:::tip
Лучше выбрать профессию, которая дополняет класс, а не дублирует его сильные стороны.
:::
<div class="see-also">
<p>Смотри также</p>
<a href="/economy/">Экономика</a> · <a href="/guides/">Гайды</a>
</div>

View File

@@ -2,6 +2,10 @@
title: "Правила" title: "Правила"
description: "Полный свод правил сервера PARABOX: пункты, подпункты, санкции и порядок разбирательств." description: "Полный свод правил сервера PARABOX: пункты, подпункты, санкции и порядок разбирательств."
--- ---
# Правила сервера **PARABOX**
---
### Как работает этот документ ### Как работает этот документ
Этот документ нужен для того, чтобы на сервере **PARABOX** были: Этот документ нужен для того, чтобы на сервере **PARABOX** были:
@@ -116,10 +120,9 @@ description: "Полный свод правил сервера PARABOX: пун
Базовый порядок урегулирования споров на сервере следующий: Базовый порядок урегулирования споров на сервере следующий:
1. добровольное мирное урегулирование; 1. добровольное мирное урегулирование;
2. консул; 2. суд;
3. президент; 3. президент и консул в пределах своих полномочий;
4. верховный суд; 4. главная администрация как высшая инстанция.
5. главная администрация как высшая инстанция.
#### Взаимная подотчётность ветвей власти #### Взаимная подотчётность ветвей власти
Президент, суд и исполнительная власть находятся в системе взаимного контроля, влияния и подотчётности. Президент, суд и исполнительная власть находятся в системе взаимного контроля, влияния и подотчётности.
@@ -173,8 +176,8 @@ description: "Полный свод правил сервера PARABOX: пун
### 1.6 Границы мира ### 1.6 Границы мира
Мир сервера ограничен следующими рамками: Мир сервера ограничен следующими рамками:
- верхний мир — **20 000 × 20 000** блоков; - верхний мир — **20 000 × 20 000** блоков (10000 блоков во все стороны сервера);
- нижний мир — **3 000 × 3 000** блоков. - нижний мир — **3 000 × 3 000** блоков (1500 блоков во все стороны сервера).
Выход за установленные границы, обход ограничений мира и попытки использовать их в ущерб серверу запрещены. Выход за установленные границы, обход ограничений мира и попытки использовать их в ущерб серверу запрещены.
@@ -259,7 +262,7 @@ description: "Полный свод правил сервера PARABOX: пун
- по инициативе президента; - по инициативе президента;
- через установленный порядок обсуждения и согласования. - через установленный порядок обсуждения и согласования.
Для вступления изменений в силу требуется согласование с администрацией и предусмотренное сервером подтверждение со стороны игроков, если такая процедура объявлена как обязательная. Также о всех изменениях в своде правил администрация должна оповещать игроков. Для вступления изменений в силу требуется согласование с администрацией и предусмотренное сервером подтверждение со стороны игроков, если такая процедура объявлена как обязательная.
--- ---
@@ -322,7 +325,6 @@ description: "Полный свод правил сервера PARABOX: пун
- блокировать проходы; - блокировать проходы;
- перекрывать общественные объекты; - перекрывать общественные объекты;
- срывать ивенты; - срывать ивенты;
- мешать лору и сюжету;
- преследовать игроков; - преследовать игроков;
- постоянно провоцировать их на конфликт; - постоянно провоцировать их на конфликт;
- использовать механики для вреда чужому прогрессу. - использовать механики для вреда чужому прогрессу.
@@ -353,7 +355,7 @@ description: "Полный свод правил сервера PARABOX: пун
На общественных объектах действуют правила, установленные их владельцами, городом, государством, президентом или судом, если они не противоречат основным правилам сервера. На общественных объектах действуют правила, установленные их владельцами, городом, государством, президентом или судом, если они не противоречат основным правилам сервера.
### 2.14 Ключевые общественные точки ### 2.14 Ключевые общественные точки
Ближайший общественный портал в Энд, незерская магистраль и иные стратегически важные точки мира, признанные общественными, не могут использоваться в личных интересах, если это ограничивает других игроков. Ближайший общественный портал в Энд и иные стратегически важные точки мира, признанные общественными, не могут использоваться в личных интересах, если это ограничивает других игроков.
Запрещено: Запрещено:
@@ -476,8 +478,8 @@ description: "Полный свод правил сервера PARABOX: пун
Администрация вправе отдельно разрешать или запрещать иные моды по своему решению. Администрация вправе отдельно разрешать или запрещать иные моды по своему решению.
### 4.4 Freecam + ReplayMode ### 4.4 Freecam и ReplayMode
Использование Freecam + ReplayMode с прохождением через блоки, просмотром скрытых помещений, баз, тайников, шахт и иных недоступных зон запрещено. Использование Freecam, ReplayMode, миникарт с отображением пещер и сущностей, или модов с хожим функционалом, таким как прохождением через блоки, просмотром скрытых помещений, баз, тайников, шахт и иных недоступных зон и сущностей запрещено.
### 4.5 Прямо запрещённые инструменты ### 4.5 Прямо запрещённые инструменты
Запрещены, в том числе: Запрещены, в том числе:
@@ -557,7 +559,7 @@ AFK допускается только в разумных пределах и
- фермы; - фермы;
- мастерские; - мастерские;
- шахтные комплексы; - шахтные комплексы;
- определенные части города; - города;
- служебные объекты; - служебные объекты;
- любые явно обозначенные или логически принадлежащие кому-либо места. - любые явно обозначенные или логически принадлежащие кому-либо места.
@@ -571,7 +573,7 @@ AFK допускается только в разумных пределах и
- признана городом, судом, президентом либо администрацией. - признана городом, судом, президентом либо администрацией.
### 5.3 Спавн ### 5.3 Спавн
Территория спавна составляет **500×500 блоков**. Территория спавна составляет **500×500 блоков** (250 блоков во все стороны от нулевых координат).
На спавне запрещены: На спавне запрещены:
@@ -583,7 +585,7 @@ AFK допускается только в разумных пределах и
- действия, мешающие использованию спавна как общественной зоны. - действия, мешающие использованию спавна как общественной зоны.
### 5.4 Регистрация города ### 5.4 Регистрация города
Город считается официальным только после подачи заявки по форме и её подтверждения. Город считается официальным только после подачи заявки и её подтверждения.
Заявка на регистрацию города подтверждается: Заявка на регистрацию города подтверждается:
@@ -600,7 +602,7 @@ AFK допускается только в разумных пределах и
- местные проекты; - местные проекты;
- участие в суде и политических процессах. - участие в суде и политических процессах.
Все внутренние правила города действуют только в части, не противоречащей правилам сервера. Внутренние правила и распорядки города, также могут быть пересмотрены решением вышестоящей власти. Все внутренние правила города действуют только в части, не противоречащей правилам сервера.
### 5.6 Открытые общественные зоны города ### 5.6 Открытые общественные зоны города
Каждый официальный город обязан иметь открытые территории для приёма игроков и нормального публичного взаимодействия. Каждый официальный город обязан иметь открытые территории для приёма игроков и нормального публичного взаимодействия.
@@ -766,15 +768,13 @@ RP является важной частью сервера **PARABOX**, но
### 6.4 Лор сервера ### 6.4 Лор сервера
Официальный лор сервера продвигается, направляется и при необходимости корректируется администрацией. Официальный лор сервера продвигается, направляется и при необходимости корректируется администрацией.
Игроки и города могут участвовать в лоре и развивать собственные сюжеты, если они: Игроки могут участвовать в лоре и развивать собственные сюжеты, если они:
- не противоречат основным правилам; - не противоречат основным правилам;
- не ломают атмосферу сервера; - не ломают атмосферу сервера;
- не присваивают игроку необоснованную власть; - не присваивают игроку необоснованную власть;
- не мешают общему развитию проекта. - не мешают общему развитию проекта.
Также игроки могут связывать свой лор и идеи, с помощью администрации, после тщательного изучения и одобрения с их стороны.
### 6.5 Политические и государственные процессы ### 6.5 Политические и государственные процессы
RP-политика, законы, указы, решения органов власти, выборы и государственные процессы допустимы, если они не противоречат правилам сервера и не превращаются в средство злоупотребления. RP-политика, законы, указы, решения органов власти, выборы и государственные процессы допустимы, если они не противоречат правилам сервера и не превращаются в средство злоупотребления.
@@ -804,7 +804,7 @@ RP-политика, законы, указы, решения органов в
### 7.2 Срок полномочий ### 7.2 Срок полномочий
Президент, судья и консул избираются на срок **1 месяц**. Президент, судья и консул избираются на срок **1 месяц**.
После завершения срока полномочий проводятся новые выборы или иная предусмотренная сервером процедура подтверждения новой власти. При этом президентом нельзя становиться более 2 сроков за общее время. После завершения срока полномочий проводятся новые выборы или иная предусмотренная сервером процедура подтверждения новой власти.
### 7.3 Выборность должностей ### 7.3 Выборность должностей
На сервере могут выбираться: На сервере могут выбираться:
@@ -818,7 +818,7 @@ RP-политика, законы, указы, решения органов в
Запрещено: Запрещено:
- одновременно занимать две или более высшие выборные должности; - одновременно занимать две или три высшие выборные должности;
- одновременно участвовать как кандидат сразу в нескольких выборах в рамках одного избирательного цикла; - одновременно участвовать как кандидат сразу в нескольких выборах в рамках одного избирательного цикла;
- использовать снятие кандидатуры с одной должности для скрытого обхода ограничений другой должности, если это нарушает порядок выборов. - использовать снятие кандидатуры с одной должности для скрытого обхода ограничений другой должности, если это нарушает порядок выборов.
@@ -1290,7 +1290,7 @@ RP-политика, законы, указы, решения органов в
Консул не получает автоматически: Консул не получает автоматически:
- административные команды; - административные команды;
- право отменять суд; - право отменять суд без причины;
- право подменять администрацию; - право подменять администрацию;
- право действовать вне закона и процедуры. - право действовать вне закона и процедуры.
@@ -1312,6 +1312,9 @@ RP-политика, законы, указы, решения органов в
- использовать служебные инструменты проверки, включая **CoreProtect**, если доступ к ним предоставлен сервером; - использовать служебные инструменты проверки, включая **CoreProtect**, если доступ к ним предоставлен сервером;
- устанавливать, кто посещал территорию, кто взаимодействовал с блоками, кто мог совершить кражу или иное действие; - устанавливать, кто посещал территорию, кто взаимодействовал с блоками, кто мог совершить кражу или иное действие;
- проводить обследования местности; - проводить обследования местности;
- проводить оперативные мероприятия и оперативные расследования в пределах закона и своей компетенции;
- собирать, фиксировать и передавать в суд улики, полученные законным способом;
- использовать данные CoreProtect и иных разрешённых сервером инструментов для получения улик против предполагаемого нарушителя;
- организовывать законные осмотры и проверки; - организовывать законные осмотры и проверки;
- проверять инвентарь игрока, если это необходимо для задержания, расследования, исполнения решения суда или иной установленной процедуры; - проверять инвентарь игрока, если это необходимо для задержания, расследования, исполнения решения суда или иной установленной процедуры;
- назначать исполнителей и распределять обязанности в рамках исполнительной ветви, если это предусмотрено устройством сервера; - назначать исполнителей и распределять обязанности в рамках исполнительной ветви, если это предусмотрено устройством сервера;
@@ -1342,7 +1345,7 @@ RP-политика, законы, указы, решения органов в
- вмешиваться в дела администрации вне своей компетенции. - вмешиваться в дела администрации вне своей компетенции.
### 11.7 Основания для действий исполнительной власти ### 11.7 Основания для действий исполнительной власти
Задержания, обследования, проверки инвентаря, охрана, конфискации и иные исполнительные действия допускаются только при наличии одного из оснований: Задержания, обследования, проверки инвентаря, охрана, конфискации, оперативные мероприятия, оперативные расследования и иные исполнительные действия допускаются только при наличии одного из оснований:
- решения суда; - решения суда;
- официального расследования; - официального расследования;
@@ -1351,6 +1354,8 @@ RP-политика, законы, указы, решения органов в
- прямого поручения уполномоченного органа сервера; - прямого поручения уполномоченного органа сервера;
- чрезвычайной ситуации, где требуется немедленное вмешательство. - чрезвычайной ситуации, где требуется немедленное вмешательство.
При оперативных расследованиях исполнительная власть вправе использовать CoreProtect и иные разрешённые сервером инструменты для поиска следов нарушений, установления действий игроков и получения улик, пригодных для передачи в суд или администрации.
### 11.8 Обязанность фиксации ### 11.8 Обязанность фиксации
Исполнительная власть обязана по возможности фиксировать свои действия. Исполнительная власть обязана по возможности фиксировать свои действия.
@@ -1398,6 +1403,14 @@ RP-политика, законы, указы, решения органов в
- политические и должностные дела; - политические и должностные дела;
- иные вопросы, переданные на рассмотрение. - иные вопросы, переданные на рассмотрение.
Суд также отвечает за:
- хранение судебных документов;
- ведение делопроизводства;
- оформление решений;
- работу с судебными материалами;
- передачу официальных документов участникам процесса.
### 12.3 Как подаётся дело ### 12.3 Как подаётся дело
Дело может быть подано через: Дело может быть подано через:
@@ -1417,7 +1430,40 @@ RP-политика, законы, указы, решения органов в
6. требования заявителя; 6. требования заявителя;
7. свидетелей, если они есть. 7. свидетелей, если они есть.
### 12.4 Ведение доказательств ### 12.4 Досудебный порядок урегулирования
До обращения в суд стороны обязаны попытаться урегулировать конфликт в досудебном порядке, если это возможно по характеру спора.
#### 12.4.1 Что включает досудебный порядок
Досудебный порядок предполагает:
- попытку мирного урегулирования;
- обращение к другой стороне с претензией;
- предложение решить вопрос без судебного разбирательства;
- фиксацию того, что спор действительно пытались урегулировать.
В суде участники не выясняют отношения заново, а излагают свою позицию, предъявляют доказательства и добиваются правового решения.
#### 12.4.2 Если досудебный порядок не соблюдён
Если досудебный порядок отсутствовал без уважительной причины, суд вправе отказать в принятии заявления или оставить дело без рассмотрения до соблюдения предварительного порядка урегулирования.
### 12.5 Государственная пошлина
Подача судебного заявления облагается фиксированной государственной пошлиной в размере **10 ар.**
Иной размер, льготы, освобождение или особый порядок могут быть установлены отдельным решением сервера, суда или администрации.
### 12.6 Предоставление доказательств до заседания
Все основные доказательства необходимо предоставить судье **до начала судебного заседания**.
#### 12.6.1 Кому можно передать доказательства
В крайнем случае доказательства могут быть переданы:
- судье;
- либо любому члену администрации, если судья временно недоступен.
#### 12.6.2 Последствия поздней подачи
Несвоевременная подача доказательств может повлиять на их оценку, допустимость или возможность учёта в конкретном заседании.
### 12.7 Ведение доказательств
Для защиты своих интересов в суде игрокам настоятельно рекомендуется вести фиксацию важных событий. Для защиты своих интересов в суде игрокам настоятельно рекомендуется вести фиксацию важных событий.
Желательно использовать: Желательно использовать:
@@ -1433,7 +1479,7 @@ RP-политика, законы, указы, решения органов в
Чем лучше сторона фиксирует события, тем проще суду установить факты. Чем лучше сторона фиксирует события, тем проще суду установить факты.
### 12.5 Доказательства ### 12.8 Доказательства
Суд вправе учитывать: Суд вправе учитывать:
- скриншоты; - скриншоты;
@@ -1444,25 +1490,69 @@ RP-политика, законы, указы, решения органов в
- показания свидетелей; - показания свидетелей;
- координаты; - координаты;
- состояние территории; - состояние территории;
- логи и технические данные, если они предоставлены уполномоченным лицом. - логи и технические данные, если они предоставлены уполномоченным лицом;
- улики, полученные исполнительной властью законным способом.
### 12.6 Поведение в суде ### 12.9 Правила поведения в судебном заседании
Стороны и участники процесса обязаны вести себя в суде уважительно. В судебном заседании участники обязаны вести себя корректно и уважительно.
За непристойное, оскорбительное, срывающее процесс или демонстративно неуважительное поведение суд может вынести: #### 12.9.1 Запрещается
Запрещается:
- предупреждение; - выяснять личные отношения вместо изложения позиции по делу;
- удаление с заседания; - бегать, прыгать и иным образом нарушать порядок;
- дополнительный штраф; - отвлекать суд, присяжных, если они предусмотрены процессом, или иных участников;
- иные процессуальные меры в пределах своих полномочий. - оскорблять присяжных, потерпевших, ответчиков, истцов, прокурора, заинтересованных лиц, понятых, свидетелей, судью и иных участников процесса;
- вмешиваться в действия суда и других участников процесса;
- мешать ведению разбирательства репликами, вопросами и комментариями без разрешения суда;
- допускать шум, спам, хаос и иные формы неуважения к процессу.
### 12.7 Участие президента в судебном процессе #### 12.9.2 Участники обязаны
Участники обязаны:
- выполнять законные требования и распоряжения судьи;
- соблюдать порядок;
- не проявлять неуважение к суду и другим участникам процесса;
- бережно относиться к имуществу суда;
- соблюдать чистоту, тишину и порядок в здании суда и на его территории.
### 12.10 Формы обращения к суду
#### 12.10.1 Допустимые формы обращения
Во время судебного заседания к суду обращаются следующим образом:
- **если гражданский процесс** — **«Уважаемый Суд»**;
- **если уголовный процесс** — **«Ваша честь»**.
### 12.11 Порядок выступления в судебном заседании
Свои объяснения, показания, вопросы другим участникам и ответы на вопросы участники дают **стоя**, если суд не разрешит иное.
#### 12.11.1 Для уголовного процесса
Участники дают объяснение своей позиции и доказывают её, **без споров между собой**.
Они не ведут взаимную полемику и не отвечают по кругу на тезисы друг друга, если суд прямо этого не разрешил.
#### 12.11.2 Для гражданского процесса
Участники дают объяснение своей позиции и доказывают её.
Допускается **один раз** ответить на **один основной тезис** противоположной стороны, без превращения заседания в спор между участниками.
### 12.12 Фото-, видео- и иная фиксация заседания
Лица, присутствующие в зале суда и осуществляющие разрешённую судом фото- и видеосъёмку, трансляцию, запись или иную фиксацию заседания, не должны мешать порядку в судебном заседании.
### 12.13 Отсутствие участника и доверенное лицо
#### 12.13.1 Участие доверенного лица
Если потерпевший, ответчик, истец или иной участник не может присутствовать на судебном заседании, вместо него может присутствовать доверенное лицо, если такой формат допустим по делу и признан судом.
#### 12.13.2 Если доверенное лицо отсутствует
Если доверенное лицо не предусмотрено либо не представлено, суд вправе провести заседание без отсутствующей стороны на основании доказательств, заранее переданных суду, в том числе через Telegram или иной официальный канал связи.
### 12.14 Поведение в суде и участие президента в процессе
#### 12.14.1 В каких ролях может выступать президент
Президент в рамках суда может выступать: Президент в рамках суда может выступать:
- как адвокат; - как адвокат;
- как подсудимый; - как подсудимый;
- как лицо, исполняющее роль прокурора. - как лицо, исполняющее роль прокурора.
#### 12.14.2 Какие ограничения действуют для президента
Однако при этом президент: Однако при этом президент:
- не получает процессуальных преимуществ; - не получает процессуальных преимуществ;
@@ -1470,27 +1560,45 @@ RP-политика, законы, указы, решения органов в
- не может требовать особого порядка только по причине должности; - не может требовать особого порядка только по причине должности;
- обязан подчиняться регламенту суда наравне с другими участниками. - обязан подчиняться регламенту суда наравне с другими участниками.
### 12.8 Ложные обращения ### 12.15 Выдача решений и материалов дела
Все официальные решения суда, ходы дела, постановления и иные документы выдаются участникам процесса после официального постановления суда для последующего:
- обжалования;
- апелляции;
- передачи в вышестоящие органы;
- исполнения решения.
### 12.16 Ложные обращения
Запрещено подавать ложные иски, фальшивые доказательства, поддельные обвинения и использовать суд как инструмент травли. Запрещено подавать ложные иски, фальшивые доказательства, поддельные обвинения и использовать суд как инструмент травли.
### 12.9 Решения суда ### 12.17 Меры за нарушение порядка в суде и решения суда
Суд может выносить, например, следующие наказания и меры: #### 12.17.1 Возможные меры
За нарушение порядка в суде либо по итогам рассмотрения дела суд может применить одну или несколько мер:
- предупреждение; - предупреждение;
- удаление с судебного заседания;
- удаление с заседания после **3 предупреждений**;
- дополнительный штраф;
- обязательство вернуть имущество; - обязательство вернуть имущество;
- компенсацию; - компенсацию;
- штраф;
- общественные работы; - общественные работы;
- тюремное заключение; - тюремное заключение;
- ограничение прав; - ограничение прав;
- временное отстранение от должности; - временное отстранение от должности;
- запрет на отдельные действия; - запрет на отдельные действия;
- мут в Minecraft при неоднократных нарушениях в игровом чате;
- мут в Discord при неоднократных нарушениях в чате или голосовых каналах;
- наложение ареста на имущество;
- ограничение свободы;
- исправительные работы;
- изъятие имущества с последующим возвращением игроку, законному владельцу либо передаче администрации по законному решению;
- лишение права занимать определённую должность или заниматься определённой деятельностью;
- иные законные меры, предусмотренные сервером. - иные законные меры, предусмотренные сервером.
### 12.10 Исполнение судебных решений ### 12.18 Исполнение судебных решений
Исполнение решений суда обеспечивает консул и исполнительная власть в пределах своих полномочий. Исполнение решений суда обеспечивает консул и исполнительная власть в пределах своих полномочий.
### 12.11 Пределы суда ### 12.19 Пределы суда
Суд не вправе легализовывать: Суд не вправе легализовывать:
- читы; - читы;
@@ -1500,10 +1608,11 @@ RP-политика, законы, указы, решения органов в
- слив данных; - слив данных;
- любые иные прямые нарушения основных правил сервера. - любые иные прямые нарушения основных правил сервера.
### 12.12 Апелляция ### 12.20 Апелляция
Сторона вправе обжаловать решение суда в установленном порядке. Высшей инстанцией по исключительным делам и конфликтам между органами власти выступает администрация. Сторона вправе обжаловать решение суда в установленном порядке. Высшей инстанцией по исключительным делам и конфликтам между органами власти выступает администрация.
### 12.13 Роль администрации в судебной системе ### 12.21 Роль администрации в судебной системе
#### 12.21.1 Функции администрации
Администрация не обязана заменять суд в обычных спорах, но выступает: Администрация не обязана заменять суд в обычных спорах, но выступает:
- высшей инстанцией; - высшей инстанцией;
@@ -1511,7 +1620,7 @@ RP-политика, законы, указы, решения органов в
- органом вмешательства в исключительных случаях; - органом вмешательства в исключительных случаях;
- финальной стороной при конфликте между формальным порядком и безопасностью сервера. - финальной стороной при конфликте между формальным порядком и безопасностью сервера.
### 12.14 Неисполнение судебного решения ### 12.22 Неисполнение судебного решения
Отказ исполнять законное решение суда может повлечь дополнительную ответственность, вплоть до вмешательства исполнительной власти или администрации. Отказ исполнять законное решение суда может повлечь дополнительную ответственность, вплоть до вмешательства исполнительной власти или администрации.
--- ---

View File

@@ -1,8 +0,0 @@
---
title: "Сюжет"
description: "Раздел сюжета сервера."
---
## Сюжет
СЕРЕЖА РЕСПЕШИ МНЕ СЮЖЕТИК И ВЧЕ ЧТО С НИМ СВЯЗАНО

View File

@@ -1,34 +0,0 @@
---
title: "Команда проекта"
description: "Кто развивает сервер: роли, ответственность и зоны поддержки."
---
## Состав команды
| Роль | Зона ответственности |
| --- | --- |
| Lead Admin | Архитектура мира и баланс |
| Content Designer | Квесты, лор, события |
| Tech Admin | Стабильность, плагины, бэкапы |
| Community Manager | Коммуникация с игроками |
## Как мы работаем
### Принцип 1
Решения по балансу принимаются на основе статистики, а не эмоций.
### Принцип 2
Критические правки публикуются с changelog.
## Как присоединиться
Следи за открытыми ролями в Discord и оставляй заявку с примерами работ.
<div class="see-also">
<p>Смотри также</p>
<a href="/contacts/">Контакты / ссылки</a> · <a href="/about-server/">О сервере</a>
</div>

View File

@@ -1,48 +0,0 @@
---
title: "Шаблон новой страницы"
description: "Готовый шаблон Markdown-страницы для быстрого добавления новых материалов."
---
## Копируй и используй
```md
---
title: "Название раздела"
description: "Краткое описание страницы"
---
## Введение
Коротко опиши, что на странице.
## Основной раздел
### Подраздел
- Пункт 1
- Пункт 2
:::tip
Добавляй подсказки через стандартные блоки Starlight.
:::
## Таблица
| Колонка | Значение |
| --- | --- |
| Пример | Текст |
<div class="see-also">
<p>Смотри также</p>
<a href="/getting-started/">Начало игры</a>
</div>
```
## Рекомендации по структуре
- Один файл = одна тема.
- Пиши короткие абзацы.
- Используй `h2` и `h3`, чтобы оглавление было полезным.
- Добавляй блок «Смотри также» в конце страницы.

View File

@@ -169,7 +169,7 @@ starlight-menu-button button::before {
} }
starlight-menu-button[aria-expanded='true'] button::before { starlight-menu-button[aria-expanded='true'] button::before {
content: ''; content: '×';
font-size: 1.02rem; font-size: 1.02rem;
letter-spacing: 0; letter-spacing: 0;
transform: none; transform: none;
@@ -320,9 +320,26 @@ starlight-menu-button button:hover {
transform: translateY(-1px); transform: translateY(-1px);
} }
/* Единый эффект свечения в момент нажатия для всех кнопок/кнопкоподобных элементов. */
:is(
button:not(:disabled),
.sl-link-button,
.map-cta-button,
.map-ghost-button,
.copy-ip-chip
):active {
transform: translateY(0) scale(0.98) !important;
box-shadow:
0 0 0 1px color-mix(in srgb, var(--sl-color-accent) 34%, transparent),
0 0 18px color-mix(in srgb, var(--sl-color-accent) 34%, transparent),
0 0 34px color-mix(in srgb, var(--wiki-blue-2) 26%, transparent) !important;
filter: saturate(1.08);
}
.sl-markdown-content h1, .sl-markdown-content h1,
.sl-markdown-content h2, .sl-markdown-content h2,
.sl-markdown-content h3 { .sl-markdown-content h3,
.sl-markdown-content h4 {
font-family: 'Sora', sans-serif; font-family: 'Sora', sans-serif;
letter-spacing: 0.005em; letter-spacing: 0.005em;
line-height: 1.24; line-height: 1.24;
@@ -346,6 +363,40 @@ starlight-menu-button button:hover {
margin-bottom: 0.5rem; margin-bottom: 0.5rem;
} }
.sl-markdown-content h4 {
margin-top: 1rem;
margin-bottom: 0.36rem;
font-size: clamp(0.96rem, 0.93rem + 0.18vw, 1.07rem);
color: color-mix(in srgb, var(--sl-color-white) 86%, var(--wiki-blue-2));
}
.sl-markdown-content .sl-heading-wrapper.level-h3 > h3 {
display: inline-flex;
align-items: center;
gap: 0.52rem;
}
.sl-markdown-content .minimal-heading-icon {
width: 1em;
height: 1em;
display: inline-block;
flex-shrink: 0;
opacity: 0.98;
background: linear-gradient(
150deg,
color-mix(in srgb, var(--wiki-purple-2) 76%, #ffffff),
color-mix(in srgb, var(--wiki-blue-2) 82%, #ffffff)
);
-webkit-mask-image: var(--icon-url);
mask-image: var(--icon-url);
-webkit-mask-size: contain;
mask-size: contain;
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
-webkit-mask-position: center;
mask-position: center;
}
.sl-markdown-content p, .sl-markdown-content p,
.sl-markdown-content li { .sl-markdown-content li {
color: var(--wiki-text); color: var(--wiki-text);
@@ -370,6 +421,61 @@ starlight-menu-button button:hover {
text-decoration-thickness: 0.07em; text-decoration-thickness: 0.07em;
} }
.sl-markdown-content :is(p, li, td, blockquote) a[href]:not(.sl-anchor-link):not(.map-cta-button):not(
.map-ghost-button
):not(.sl-link-button):not([href^='#']) {
display: inline-flex;
align-items: center;
justify-content: center;
min-height: 2.44rem;
max-width: min(100%, 100ch);
margin: 0.1rem 0.2rem 0.1rem 0;
padding: 0.55rem 1rem;
border: 1px solid color-mix(in srgb, var(--sl-color-accent) 48%, transparent);
border-radius: 0.2rem;
background: linear-gradient(
110deg,
color-mix(in srgb, var(--wiki-blue-2) 76%, #233145),
color-mix(in srgb, var(--wiki-purple-2) 66%, #273850)
);
color: #f8fbff;
text-decoration: none;
font-family: 'Sora', sans-serif;
font-weight: 600;
font-size: 0.95rem;
letter-spacing: 0.008em;
line-height: 1;
overflow-wrap: anywhere;
box-shadow: 0 6px 14px color-mix(in srgb, var(--sl-color-accent) 18%, transparent);
transition: transform 170ms ease, border-color 170ms ease, box-shadow 170ms ease;
}
.sl-markdown-content :is(p, li, td, blockquote) a[href]:not(.sl-anchor-link):not(.map-cta-button):not(
.map-ghost-button
):not(.sl-link-button):not([href^='#']):hover {
color: #ffffff;
text-decoration: none;
transform: translateY(-1px);
border-color: color-mix(in srgb, var(--sl-color-accent) 64%, transparent);
box-shadow: 0 10px 18px color-mix(in srgb, var(--sl-color-accent) 24%, transparent);
}
.sl-markdown-content :is(p, li, td, blockquote) a[href]:not(.sl-anchor-link):not(.map-cta-button):not(
.map-ghost-button
):not(.sl-link-button):not([href^='#']):focus-visible {
outline: none;
border-color: color-mix(in srgb, var(--sl-color-accent) 72%, transparent);
box-shadow:
0 0 0 1px color-mix(in srgb, var(--sl-color-accent) 30%, transparent),
0 0 0 4px color-mix(in srgb, var(--sl-color-accent) 20%, transparent);
}
.sl-markdown-content :is(p, li, td, blockquote) a[href]:not(.sl-anchor-link):not(.map-cta-button):not(
.map-ghost-button
):not(.sl-link-button):not([href^='#']):active {
transform: translateY(0) scale(0.98);
}
.sl-markdown-content code { .sl-markdown-content code {
border-radius: 0.16rem; border-radius: 0.16rem;
border: 1px solid color-mix(in srgb, var(--sl-color-hairline) 78%, transparent); border: 1px solid color-mix(in srgb, var(--sl-color-hairline) 78%, transparent);
@@ -622,6 +728,159 @@ starlight-theme-select .caret {
margin-bottom: 0.45rem; margin-bottom: 0.45rem;
} }
.craft-grid {
display: grid;
gap: 1rem;
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
grid-auto-rows: 1fr;
margin: 1rem 0 1.3rem;
}
.craft-grid > .craft-card {
margin-top: 0;
}
.craft-catalog {
margin-top: 0.95rem;
}
.craft-controls {
display: grid;
gap: 0.72rem;
margin: 0 0 1rem;
}
.craft-search-field {
display: grid;
gap: 0.36rem;
font-weight: 700;
font-size: 0.95rem;
color: color-mix(in srgb, var(--wiki-text) 92%, var(--sl-color-white));
}
.craft-search-input {
width: 100%;
min-height: 2.42rem;
border-radius: 0.18rem;
border: 1px solid color-mix(in srgb, var(--sl-color-hairline) 82%, transparent);
background: color-mix(in srgb, var(--wiki-card) 92%, transparent);
color: var(--wiki-text);
padding: 0.5rem 0.68rem;
font: inherit;
transition: border-color 150ms ease, box-shadow 150ms ease;
}
.craft-search-input::placeholder {
color: color-mix(in srgb, var(--wiki-muted) 78%, var(--sl-color-white));
}
.craft-search-input:focus-visible {
outline: none;
border-color: color-mix(in srgb, var(--sl-color-accent) 68%, transparent);
box-shadow:
0 0 0 1px color-mix(in srgb, var(--sl-color-accent) 30%, transparent),
0 0 0 4px color-mix(in srgb, var(--sl-color-accent) 18%, transparent);
}
.craft-filter-group {
display: flex;
flex-wrap: wrap;
gap: 0.48rem;
}
.craft-filter-chip {
display: inline-flex;
align-items: center;
justify-content: center;
min-height: 2.1rem;
border-radius: 999px;
border: 1px solid color-mix(in srgb, var(--sl-color-hairline) 85%, transparent);
background: color-mix(in srgb, var(--wiki-card) 92%, transparent);
color: color-mix(in srgb, var(--wiki-text) 92%, var(--sl-color-white));
padding: 0.4rem 0.82rem;
font-family: 'Sora', sans-serif;
font-weight: 600;
font-size: 0.84rem;
letter-spacing: 0.008em;
cursor: pointer;
transition:
transform 150ms ease,
border-color 150ms ease,
background 150ms ease,
color 150ms ease;
}
.craft-filter-chip:hover {
transform: translateY(-1px);
border-color: color-mix(in srgb, var(--sl-color-accent) 42%, transparent);
}
.craft-filter-chip.is-active {
border-color: color-mix(in srgb, var(--sl-color-accent) 56%, transparent);
background: linear-gradient(
120deg,
color-mix(in srgb, var(--wiki-blue-2) 74%, #233145),
color-mix(in srgb, var(--wiki-purple-2) 64%, #273850)
);
color: #f7fbff;
}
.craft-empty {
margin: 0.18rem 0 1.02rem;
border: 1px dashed color-mix(in srgb, var(--sl-color-accent) 34%, transparent);
border-radius: 0.16rem;
background: color-mix(in srgb, var(--sl-color-accent-low) 66%, transparent);
padding: 0.62rem 0.74rem;
font-size: 0.93rem;
}
.craft-group {
margin-bottom: 1.15rem;
}
.craft-group > h3 {
margin-bottom: 0.58rem;
}
.craft-card {
padding: 0.82rem 0.86rem;
display: flex;
flex-direction: column;
height: 100%;
}
.craft-card:hover {
transform: none;
}
.craft-card h3 {
margin: 0 0 0.6rem;
font-size: 1rem;
line-height: 1.35;
min-height: calc(1.35em * 2);
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.craft-card-image {
display: block;
width: 100%;
aspect-ratio: 346 / 167;
object-fit: cover;
border-radius: 0.18rem;
border: 1px solid color-mix(in srgb, var(--sl-color-hairline) 88%, transparent);
background: color-mix(in srgb, #ffffff 18%, transparent);
box-shadow: var(--sl-shadow-sm);
image-rendering: pixelated;
}
.craft-card[hidden],
.craft-group[hidden] {
display: none !important;
}
.alcohol-nav-card { .alcohol-nav-card {
display: block; display: block;
color: inherit; color: inherit;
@@ -690,44 +949,219 @@ starlight-theme-select .caret {
font-weight: 700; font-weight: 700;
} }
.map-cta-wrap { .ip-main-grid {
display: grid;
gap: 0.96rem;
grid-template-columns: repeat(2, minmax(0, 1fr));
grid-auto-rows: minmax(0, 1fr);
align-items: stretch;
margin: 0.95rem 0 0.8rem;
}
.ip-main-card {
border: 1px solid color-mix(in srgb, var(--sl-color-accent) 28%, var(--sl-color-hairline));
border-radius: 0.2rem;
padding: 1rem 1.02rem;
height: 100%;
min-height: 11.2rem;
display: flex;
flex-direction: column;
background:
linear-gradient(
160deg,
color-mix(in srgb, var(--wiki-purple-2) 12%, transparent),
color-mix(in srgb, var(--wiki-blue-2) 8%, transparent)
),
color-mix(in srgb, var(--wiki-card) 96%, transparent);
}
.ip-main-grid > .ip-main-card {
margin: 0 !important;
align-self: stretch;
}
.ip-main-grid > .ip-main-card + .ip-main-card {
margin-top: 0 !important;
}
.ip-main-card h3 {
margin: 0 0 0.52rem;
font-family: 'Sora', sans-serif;
font-size: 1.02rem;
line-height: 1.25;
}
.ip-main-card ul {
margin: 0;
padding-inline-start: 1.06rem;
display: grid;
gap: 0.52rem;
align-content: start;
}
.ip-main-card li {
margin: 0;
line-height: 1.4;
}
.copy-ip-chip {
appearance: none;
border: 1px solid color-mix(in srgb, var(--sl-color-accent) 48%, transparent);
border-radius: 0.2rem;
background: linear-gradient(
110deg,
color-mix(in srgb, var(--wiki-blue-2) 76%, #233145),
color-mix(in srgb, var(--wiki-purple-2) 66%, #273850)
);
color: #f8fbff;
display: inline-flex;
align-items: center;
justify-content: center;
min-height: 2rem;
padding: 0.36rem 0.72rem;
margin: 0 0 0 0.24rem;
cursor: pointer;
text-decoration: none;
font-family: 'Sora', sans-serif;
font-weight: 600;
font-size: 0.86rem;
letter-spacing: 0.008em;
line-height: 1;
box-shadow: 0 6px 14px color-mix(in srgb, var(--sl-color-accent) 18%, transparent);
transition: transform 170ms ease, border-color 170ms ease, box-shadow 170ms ease;
}
.copy-ip-chip code {
margin: 0;
border: 0;
background: transparent;
display: inline-block;
padding: 0;
font-size: inherit;
font-family: inherit;
font-weight: inherit;
line-height: 1.2;
color: inherit;
}
.copy-ip-chip:hover {
color: #ffffff;
transform: translateY(-1px);
border-color: color-mix(in srgb, var(--sl-color-accent) 66%, transparent);
box-shadow: 0 10px 18px color-mix(in srgb, var(--sl-color-accent) 24%, transparent);
}
.copy-ip-chip:focus-visible {
outline: none;
border-color: color-mix(in srgb, var(--sl-color-accent) 72%, transparent);
box-shadow:
0 0 0 1px color-mix(in srgb, var(--sl-color-accent) 30%, transparent),
0 0 0 4px color-mix(in srgb, var(--sl-color-accent) 20%, transparent);
}
.copy-ip-chip.is-copied {
border-color: color-mix(in srgb, #7ed49b 66%, transparent);
background: linear-gradient(
110deg,
color-mix(in srgb, #63b888 76%, #223b2f),
color-mix(in srgb, #5ccd9f 66%, #26463b)
);
}
.copy-ip-chip.is-copied::after {
content: '';
}
.copy-ip-chip.is-copy-error {
border-color: color-mix(in srgb, #ef6f85 74%, transparent);
background: linear-gradient(
110deg,
color-mix(in srgb, #d56b7f 78%, #3b242a),
color-mix(in srgb, #cf6f90 68%, #3f2532)
);
}
.copy-ip-chip.is-copy-error::after {
content: '';
}
.ip-main-note {
margin-top: 0.52rem;
border: 1px solid color-mix(in srgb, var(--sl-color-accent) 30%, transparent);
border-radius: 0.18rem;
padding: 0.58rem 0.72rem;
background: color-mix(in srgb, var(--sl-color-accent-low) 66%, transparent);
color: var(--wiki-text);
font-size: 0.94rem;
}
.map-actions {
margin-top: 1rem; margin-top: 1rem;
display: flex;
flex-wrap: wrap;
gap: 0.62rem;
} }
.map-cta-button { .map-cta-button {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
min-height: 2.6rem; min-height: 2.44rem;
padding: 0.64rem 1.15rem; padding: 0.55rem 1rem;
border-radius: 0.2rem; border-radius: 0.2rem;
border: 1px solid color-mix(in srgb, var(--sl-color-accent) 55%, transparent); border: 1px solid color-mix(in srgb, var(--sl-color-accent) 48%, transparent);
background: linear-gradient( background: linear-gradient(
140deg, 110deg,
color-mix(in srgb, var(--wiki-purple-2) 72%, #1b2434), color-mix(in srgb, var(--wiki-blue-2) 76%, #233145),
color-mix(in srgb, var(--wiki-blue-2) 78%, #1b2434) color-mix(in srgb, var(--wiki-purple-2) 66%, #273850)
); );
color: #f5f9ff; color: #f8fbff;
text-decoration: none; text-decoration: none;
font-family: 'Sora', sans-serif; font-family: 'Sora', sans-serif;
font-weight: 600; font-weight: 600;
letter-spacing: 0.01em; font-size: 0.95rem;
box-shadow: letter-spacing: 0.008em;
0 8px 18px color-mix(in srgb, var(--sl-color-accent) 25%, transparent), box-shadow: 0 6px 14px color-mix(in srgb, var(--sl-color-accent) 18%, transparent);
0 0 0 1px color-mix(in srgb, var(--sl-color-accent) 18%, transparent); transition: transform 170ms ease, border-color 170ms ease, box-shadow 170ms ease;
transition: transform 170ms ease, border-color 170ms ease, box-shadow 170ms ease, filter 170ms ease;
} }
.map-cta-button:hover { .map-cta-button:hover {
color: #ffffff; color: #ffffff;
text-decoration: none; text-decoration: none;
transform: translateY(-1px); transform: translateY(-1px);
border-color: color-mix(in srgb, var(--sl-color-accent) 70%, transparent); border-color: color-mix(in srgb, var(--sl-color-accent) 66%, transparent);
box-shadow: box-shadow: 0 10px 18px color-mix(in srgb, var(--sl-color-accent) 24%, transparent);
0 12px 22px color-mix(in srgb, var(--sl-color-accent) 32%, transparent), }
0 0 0 1px color-mix(in srgb, var(--sl-color-accent) 24%, transparent),
0 0 16px color-mix(in srgb, var(--sl-color-accent) 24%, transparent); .map-ghost-button {
filter: saturate(1.06); display: inline-flex;
align-items: center;
justify-content: center;
min-height: 2.44rem;
padding: 0.55rem 1rem;
border-radius: 0.2rem;
border: 1px solid color-mix(in srgb, var(--sl-color-accent) 48%, transparent);
background: linear-gradient(
110deg,
color-mix(in srgb, var(--wiki-blue-2) 76%, #233145),
color-mix(in srgb, var(--wiki-purple-2) 66%, #273850)
);
color: #f8fbff;
text-decoration: none;
font-family: 'Sora', sans-serif;
font-weight: 600;
font-size: 0.95rem;
letter-spacing: 0.008em;
box-shadow: 0 6px 14px color-mix(in srgb, var(--sl-color-accent) 18%, transparent);
transition: transform 170ms ease, border-color 170ms ease, box-shadow 170ms ease;
}
.map-ghost-button:hover {
color: #ffffff;
text-decoration: none;
transform: translateY(-1px);
border-color: color-mix(in srgb, var(--sl-color-accent) 66%, transparent);
box-shadow: 0 10px 18px color-mix(in srgb, var(--sl-color-accent) 24%, transparent);
} }
@media (min-width: 50rem) { @media (min-width: 50rem) {
@@ -746,6 +1180,10 @@ starlight-theme-select .caret {
} }
@media (max-width: 50rem) { @media (max-width: 50rem) {
.ip-main-grid {
grid-template-columns: 1fr;
}
.wiki-header { .wiki-header {
gap: 0.5rem; gap: 0.5rem;
} }
@@ -825,4 +1263,19 @@ starlight-theme-select .caret {
border-radius: 0.16rem; border-radius: 0.16rem;
padding: 0.92rem 0.84rem; padding: 0.92rem 0.84rem;
} }
.map-actions {
flex-direction: column;
align-items: stretch;
}
.map-cta-button,
.map-ghost-button {
width: 100%;
justify-content: center;
}
.copy-ip-chip {
margin-inline-start: 0.2rem;
}
} }