diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0d3351c --- /dev/null +++ b/Makefile @@ -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 \ No newline at end of file diff --git a/astro.config.mjs b/astro.config.mjs index 73ae1df..7d41e1d 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -48,7 +48,6 @@ export default defineConfig({ label: 'О сервере', items: [ { label: 'Главная', link: '/' }, - { label: 'Сюжет', link: '/story/' }, { label: 'Начало игры', link: '/getting-started/' } ] }, @@ -67,7 +66,6 @@ export default defineConfig({ { label: 'Команды', link: '/commands/' }, { label: 'Города', link: '/cities/' }, { label: 'Крафты', link: '/crafting/' }, - { label: 'SkinRestore', link: '/skinrestore/' }, { label: 'Алкоголь', items: [ diff --git a/docker-compose.yml b/docker-compose.yml index c399f4f..0055076 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,11 +1,15 @@ -name: parabox-wiki - services: wiki: build: context: . dockerfile: Dockerfile container_name: parabox-wiki - ports: - - "4321:80" + #ports: + #- "4321:80" restart: unless-stopped + networks: + - proxy + +networks: + proxy: + external: true diff --git a/public/crafts/anvil-variant-base.png b/public/crafts/anvil-variant-base.png new file mode 100644 index 0000000..b923e64 Binary files /dev/null and b/public/crafts/anvil-variant-base.png differ diff --git a/public/crafts/anvil-variant-l.png b/public/crafts/anvil-variant-l.png new file mode 100644 index 0000000..c5e51a9 Binary files /dev/null and b/public/crafts/anvil-variant-l.png differ diff --git a/public/crafts/bell.png b/public/crafts/bell.png new file mode 100644 index 0000000..37676b8 Binary files /dev/null and b/public/crafts/bell.png differ diff --git a/public/crafts/bundle.png b/public/crafts/bundle.png new file mode 100644 index 0000000..a6cb3c3 Binary files /dev/null and b/public/crafts/bundle.png differ diff --git a/public/crafts/cartography-table.png b/public/crafts/cartography-table.png new file mode 100644 index 0000000..e8f6647 Binary files /dev/null and b/public/crafts/cartography-table.png differ diff --git a/public/crafts/clock-to-gold-ingot-smelting.png b/public/crafts/clock-to-gold-ingot-smelting.png new file mode 100644 index 0000000..f9ecf1a Binary files /dev/null and b/public/crafts/clock-to-gold-ingot-smelting.png differ diff --git a/public/crafts/compass-to-iron-ingot-smelting.png b/public/crafts/compass-to-iron-ingot-smelting.png new file mode 100644 index 0000000..2f10926 Binary files /dev/null and b/public/crafts/compass-to-iron-ingot-smelting.png differ diff --git a/public/crafts/diamond-ore-variant-k.png b/public/crafts/diamond-ore-variant-k.png new file mode 100644 index 0000000..34a02a8 Binary files /dev/null and b/public/crafts/diamond-ore-variant-k.png differ diff --git a/public/crafts/diamond-ore-variant-s.png b/public/crafts/diamond-ore-variant-s.png new file mode 100644 index 0000000..3631677 Binary files /dev/null and b/public/crafts/diamond-ore-variant-s.png differ diff --git a/public/crafts/dispenser.png b/public/crafts/dispenser.png new file mode 100644 index 0000000..86b6661 Binary files /dev/null and b/public/crafts/dispenser.png differ diff --git a/public/crafts/dragons-breath.png b/public/crafts/dragons-breath.png new file mode 100644 index 0000000..f77f6f9 Binary files /dev/null and b/public/crafts/dragons-breath.png differ diff --git a/public/crafts/enchanted-book.png b/public/crafts/enchanted-book.png new file mode 100644 index 0000000..9e06912 Binary files /dev/null and b/public/crafts/enchanted-book.png differ diff --git a/public/crafts/fletching-table.png b/public/crafts/fletching-table.png new file mode 100644 index 0000000..dc3f51a Binary files /dev/null and b/public/crafts/fletching-table.png differ diff --git a/public/crafts/glow-ink-sac.png b/public/crafts/glow-ink-sac.png new file mode 100644 index 0000000..2809894 Binary files /dev/null and b/public/crafts/glow-ink-sac.png differ diff --git a/public/crafts/invisible-glow-item-frame.png b/public/crafts/invisible-glow-item-frame.png new file mode 100644 index 0000000..67580bd Binary files /dev/null and b/public/crafts/invisible-glow-item-frame.png differ diff --git a/public/crafts/invisible-item-frame.png b/public/crafts/invisible-item-frame.png new file mode 100644 index 0000000..f23d67a Binary files /dev/null and b/public/crafts/invisible-item-frame.png differ diff --git a/public/crafts/invisible-light.png b/public/crafts/invisible-light.png new file mode 100644 index 0000000..24fe8f9 Binary files /dev/null and b/public/crafts/invisible-light.png differ diff --git a/public/crafts/jukebox.png b/public/crafts/jukebox.png new file mode 100644 index 0000000..c1275fb Binary files /dev/null and b/public/crafts/jukebox.png differ diff --git a/public/crafts/knowledge-book.png b/public/crafts/knowledge-book.png new file mode 100644 index 0000000..ee520f8 Binary files /dev/null and b/public/crafts/knowledge-book.png differ diff --git a/public/crafts/loom.png b/public/crafts/loom.png new file mode 100644 index 0000000..1b63ed6 Binary files /dev/null and b/public/crafts/loom.png differ diff --git a/public/crafts/name-tag.png b/public/crafts/name-tag.png new file mode 100644 index 0000000..cf58099 Binary files /dev/null and b/public/crafts/name-tag.png differ diff --git a/public/crafts/note-block.png b/public/crafts/note-block.png new file mode 100644 index 0000000..fed13c5 Binary files /dev/null and b/public/crafts/note-block.png differ diff --git a/public/crafts/phantom-membrane.png b/public/crafts/phantom-membrane.png new file mode 100644 index 0000000..333274f Binary files /dev/null and b/public/crafts/phantom-membrane.png differ diff --git a/public/crafts/recovery-compass-to-compass-smelting.png b/public/crafts/recovery-compass-to-compass-smelting.png new file mode 100644 index 0000000..6544c31 Binary files /dev/null and b/public/crafts/recovery-compass-to-compass-smelting.png differ diff --git a/public/crafts/red-glass-smelting.png b/public/crafts/red-glass-smelting.png new file mode 100644 index 0000000..e52a78e Binary files /dev/null and b/public/crafts/red-glass-smelting.png differ diff --git a/public/crafts/stripped-log-stonecutter.png b/public/crafts/stripped-log-stonecutter.png new file mode 100644 index 0000000..2e776a6 Binary files /dev/null and b/public/crafts/stripped-log-stonecutter.png differ diff --git a/public/crafts/sturdy-slab.png b/public/crafts/sturdy-slab.png new file mode 100644 index 0000000..76745fd Binary files /dev/null and b/public/crafts/sturdy-slab.png differ diff --git a/public/photo_2026-03-14_11-18-15.jpg b/public/photo_2026-03-14_11-18-15.jpg deleted file mode 100644 index 5e445b4..0000000 Binary files a/public/photo_2026-03-14_11-18-15.jpg and /dev/null differ diff --git a/src/components/WikiHeader.astro b/src/components/WikiHeader.astro index 936397a..00048a3 100644 --- a/src/components/WikiHeader.astro +++ b/src/components/WikiHeader.astro @@ -331,6 +331,101 @@ const topLinks = [ }); }; + 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 targets = [{ label: 'Алкоголь', href: '/alcohol/' }]; const labelNodes = document.querySelectorAll('.sidebar-content details > summary .group-label .large'); @@ -407,6 +502,7 @@ const topLinks = [ decorateSectionIcons(); annotateLinkDestinations(); bindCopyIpChips(); + bindCraftCatalogFilters(); setReadProgress(); window.addEventListener('scroll', setReadProgress, { passive: true }); window.addEventListener('resize', setReadProgress); @@ -425,6 +521,7 @@ const topLinks = [ decorateSectionIcons(); annotateLinkDestinations(); bindCopyIpChips(); + bindCraftCatalogFilters(); setReadProgress(); }); diff --git a/src/content/docs/about-server.md b/src/content/docs/about-server.md index ecb294f..1064940 100644 --- a/src/content/docs/about-server.md +++ b/src/content/docs/about-server.md @@ -13,14 +13,6 @@ description: "Концепция мира, формат сервера и осн - Выживание с RPG-элементами - Упор на исследование и кооператив -## Лор в двух словах - -После Раскола Неба мир разделился на слои. Игроки находят обломки карт, восстанавливают порталы и открывают утраченные ремёсла. - -:::caution -Некоторые сюжетные зоны открываются только после выполнения цепочки квестов. -::: - ## Техническая база | Параметр | Значение | diff --git a/src/content/docs/commands.md b/src/content/docs/commands.md index d8cefdf..b57b664 100644 --- a/src/content/docs/commands.md +++ b/src/content/docs/commands.md @@ -30,6 +30,16 @@ description: "Справочник игровых команд: чат, личн - `/coin` - подбросить монетку. - `/dice` - бросить кубик. +### Кастомные пластинки + +- `/disc burn [name]` - создать кастомную пластинку из аудио по URL. +- `/disc erase` - вернуть кастомную пластинку к обычному виду. +- `/disc search ` - найти треки на YouTube. + +:::note +Для `/disc burn` нужно держать музыкальную пластинку в руке. +::: + ### RP и взаимодействие - `/do <действие>` - RP-описание действия от третьего лица. @@ -39,11 +49,33 @@ description: "Справочник игровых команд: чат, личн ### Статус игрока - `/afk` - включить или выключить режим AFK. +- `/crawl` - позволяет игроку ползти. +- `/sit` - позволяет игроку сидеть. +- `/lay` - позволяет игроку лечь. + +### ImageFrame (изображения на картах) + +- `/imageframe select` - выбрать рамки, в которые будет поставлено изображение. +- `/imageframe create ` - создать новое изображение на картах. +- `/imageframe create selection` - создать изображение и сразу разместить его в выбранных рамках. +- `/imageframe get ` - получить ранее созданное вами изображение. +- `/imageframe get selection` - поставить ранее созданное изображение сразу в выбранные рамки. +- `/imageframe list` - показать список ваших созданных изображений. +- `/imageframe info` - показать информацию об изображении, которое вы держите в руке. +- `/imageframe refresh [image_name] [new_url]` - обновить изображение из источника (при необходимости с новой ссылкой). +- `/imageframe rename ` - переименовать ваше изображение. +- `/imageframe delete ` - удалить ваше изображение. + +:::note +Для `/imageframe create` используйте прямую ссылку на изображение. +`` и `` - это размер в картах (например `2 2` для сетки 2x2). +::: ### Информация - `/ping` - узнать задержку (пинг). - `/toponline` - посмотреть топ игроков по наигранному времени. +- `/breweryx info` - показать уровень опьянения. ### Символы diff --git a/src/content/docs/crafting.md b/src/content/docs/crafting.md index 40148e3..e0611f4 100644 --- a/src/content/docs/crafting.md +++ b/src/content/docs/crafting.md @@ -1,18 +1,155 @@ ---- +--- title: "Крафты" description: "Раздел по кастомным крафтам сервера PARABOX." --- -## Статус раздела +## Каталог крафтов -Раздел в подготовке. Здесь будет полная база кастомных крафтов. +
+
+ +
+ + + + +
+
-## Что появится + -- рецепты основных предметов сервера; -- ограничения по доступу к крафтам; -- примеры прогрессии по этапам игры. +
+

Спец-предметы

+
+
+

Невидимая рамка

+ Рецепт невидимой рамки +
+
+

Невидимая светящаяся рамка

+ Рецепт невидимой светящейся рамки +
+
+

Невидимый свет

+ Рецепт невидимого света +
+
+

Чародейская книга

+ Рецепт чародейской книги +
+
+

Книга знаний

+ Рецепт книги знаний +
+
+

Дыхание дракона

+ Рецепт дыхания дракона +
+
+

Светящиеся чернила

+ Рецепт светящихся чернил +
+
+

Мембрана фантома

+ Рецепт мембраны фантома +
+
+

Бирка

+ Рецепт бирки +
+
+

Мешок

+ Рецепт мешка +
+
+
-:::note -Если нужен конкретный рецепт раньше, уточните его у администрации или в профильном канале. -::: +
+

Блоки и рабочие станции

+
+
+

Стол лучника

+ Рецепт стола лучника +
+
+

Стол картографа

+ Рецепт стола картографа +
+
+

Ткацкий станок

+ Рецепт ткацкого станка +
+
+

Нотный блок

+ Рецепт нотного блока +
+
+

Проигрыватель

+ Рецепт проигрывателя +
+
+

Раздатчик

+ Рецепт раздатчика +
+
+

Колокол

+ Рецепт колокола +
+
+

Обтесанное бревно

+ Рецепт обтесанного бревна в камнерезе +
+
+

Прочный полублок

+ Рецепт прочного полублока +
+
+

Наковальня (вариант 1)

+ Первый вариант рецепта наковальни +
+
+

Наковальня (вариант 2)

+ Второй вариант рецепта наковальни +
+
+
+ +
+

Переработка и конверсия

+
+
+

Компас из компаса восстановления

+ Переплавка компаса восстановления в обычный компас +
+
+

Железный слиток из компаса

+ Переплавка компаса в железный слиток +
+
+

Золотой слиток из часов

+ Переплавка часов в золотой слиток +
+
+

Красное стекло

+ Переплавка в красное стекло +
+
+

Алмазная руда (вариант 1)

+ Первый вариант рецепта алмазной руды +
+
+

Алмазная руда (вариант 2)

+ Второй вариант рецепта алмазной руды +
+
+
+
diff --git a/src/content/docs/general.md b/src/content/docs/general.md index 78cac55..5555bd6 100644 --- a/src/content/docs/general.md +++ b/src/content/docs/general.md @@ -15,9 +15,6 @@ description: "Общая информация и веб-карта сервер Открыть веб-карту - - Как использовать карту для городов - --- @@ -36,3 +33,27 @@ description: "Общая информация и веб-карта сервер 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 работает в бета-режиме: отдельные параметры или ограничения могут меняться в следующих патчах. +::: diff --git a/src/content/docs/getting-started.md b/src/content/docs/getting-started.md index 2f4d556..dc76557 100644 --- a/src/content/docs/getting-started.md +++ b/src/content/docs/getting-started.md @@ -20,10 +20,3 @@ description: "Как подать заявку на сервер PARABOX и чт 1. Как к вам обращаться (имя или псевдоним). 2. Ваш никнейм для привязки к серверу. 3. От какого проекта вы пришли, или откуда узнали о сервере. - -## После одобрения - -1. Подключитесь по адресу `mc.rpcm.su`. -2. Пройдите регистрацию в игре. -3. Выберите город для вступления или создайте свой. -4. Ознакомьтесь с правилами и базовыми механиками. diff --git a/src/styles/wiki-egames.css b/src/styles/wiki-egames.css index b48d8f6..bd9e5c6 100644 --- a/src/styles/wiki-egames.css +++ b/src/styles/wiki-egames.css @@ -728,6 +728,159 @@ starlight-theme-select .caret { 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 { display: block; color: inherit;