feat: update design

This commit is contained in:
2026-06-11 12:48:42 +05:00
parent fad4d81c52
commit 3a8c9fe47a
9 changed files with 269 additions and 329 deletions
+2 -2
View File
@@ -1,6 +1,6 @@
// @ts-check
import { defineConfig } from 'astro/config';
import tailwindcss from '@tailwindcss/vite';
import tailwindcss from "@tailwindcss/vite";
import { defineConfig } from "astro/config";
export default defineConfig({
vite: {
+5 -4
View File
@@ -1,6 +1,8 @@
<footer class="mt-16 border-t border-foreground/25 bg-card/60">
<div class="mx-auto max-w-5xl px-4 py-8 sm:px-6">
<div class="flex flex-col justify-between gap-4 text-[0.7rem] uppercase tracking-wider text-muted-foreground sm:flex-row">
<div
class="flex flex-col justify-between gap-4 text-[0.7rem] uppercase tracking-wider text-muted-foreground sm:flex-row"
>
<p>
© <span class="text-foreground">Дачно-Наблюдательный Трибунал №7</span>
· Кооператив «Заря-9»
@@ -8,9 +10,8 @@
<p>Форма А-13 · Хранить вечно · Не выносить за периметр</p>
</div>
<p class="mt-4 max-w-2xl text-[0.7rem] leading-relaxed text-muted-foreground">
Все материалы являются художественным вымыслом. Любое совпадение с
реальными грядками, соседями и небесными телами случайно. Разглашение
преследуется лишением компоста.
Все материалы являются художественным вымыслом. Любое совпадение с реальными грядками, соседями и небесными телами
случайно. Разглашение преследуется лишением талона на интернет.
</p>
</div>
</footer>
+34 -30
View File
@@ -1,16 +1,16 @@
---
import BaseLayout from './base.astro'
import SiteHeader from '../components/SiteHeader.astro'
import SiteFooter from '../components/SiteFooter.astro'
import Perforation from '../components/Perforation.astro'
import Perforation from "../components/Perforation.astro";
import SiteFooter from "../components/SiteFooter.astro";
import SiteHeader from "../components/SiteHeader.astro";
import BaseLayout from "./base.astro";
interface Props {
title: string
description?: string
code?: string
title: string;
description?: string;
code?: string;
}
const { title, description, code } = Astro.props as Props
const { title, description, code } = Astro.props as Props;
---
<BaseLayout title={`${title} // Архив ДНТ-7`} description={description}>
@@ -18,9 +18,11 @@ const { title, description, code } = Astro.props as Props
<SiteHeader />
<div class="banner-classified border-y border-foreground/30">
<div class="mx-auto flex max-w-4xl items-center justify-between gap-4 px-4 py-1.5 text-[0.65rem] font-700 uppercase tracking-[0.2em] sm:px-6">
<div
class="mx-auto flex max-w-4xl items-center justify-between gap-4 px-4 py-1.5 text-[0.65rem] font-700 uppercase tracking-[0.2em] sm:px-6"
>
<span>Для служебного пользования</span>
<span class="hidden sm:inline">{code || 'МДС'}</span>
<span class="hidden sm:inline">{code || "МДС"}</span>
<span>Экз. № 1</span>
</div>
</div>
@@ -34,7 +36,7 @@ const { title, description, code } = Astro.props as Props
</a>
<article class="paper relative mt-4 -rotate-[0.3deg] p-6 sm:p-10">
<span class="tape -top-3 left-1/2 hidden -translate-x-1/2 rotate-1 sm:block" aria-hidden="true" />
<span class="tape -top-3 left-1/2 hidden -translate-x-1/2 rotate-1 sm:block" aria-hidden="true"></span>
<div class="pointer-events-none absolute right-4 top-4 sm:right-8 sm:top-10">
<img
@@ -47,7 +49,9 @@ const { title, description, code } = Astro.props as Props
</div>
<header class="pb-5">
<h1 class="max-w-2xl text-balance font-heading text-3xl font-700 uppercase leading-[0.95] tracking-tight sm:text-5xl">
<h1
class="max-w-2xl text-balance font-heading text-3xl font-700 uppercase leading-[0.95] tracking-tight sm:text-5xl"
>
{title}
</h1>
<hr class="rule rule-red mt-5" />
@@ -69,8 +73,8 @@ const { title, description, code } = Astro.props as Props
<style>
.doc-content {
font-size: 0.875rem;
line-height: 1.625;
font-size: 0.9375rem;
line-height: 1.75;
color: oklch(0.28 0.03 52 / 0.9);
}
.doc-content h2 {
@@ -78,19 +82,19 @@ const { title, description, code } = Astro.props as Props
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.05em;
font-size: 1.125rem;
margin-top: 2.5rem;
margin-bottom: 1rem;
padding-bottom: 0.25rem;
font-size: 1.25rem;
margin-top: 3rem;
margin-bottom: 1.25rem;
padding-bottom: 0.35rem;
border-bottom: 1px solid oklch(0.45 0.04 56 / 0.3);
}
.doc-content h3 {
font-family: var(--font-heading);
font-weight: 600;
text-transform: uppercase;
font-size: 0.9375rem;
margin-top: 1.5rem;
margin-bottom: 0.75rem;
font-size: 1rem;
margin-top: 2rem;
margin-bottom: 1rem;
color: var(--primary);
}
.doc-content h2:first-child {
@@ -101,7 +105,7 @@ const { title, description, code } = Astro.props as Props
margin-top: 0;
}
.doc-content p {
margin-bottom: 0.75rem;
margin-bottom: 1.25rem;
}
.doc-content strong {
font-weight: 700;
@@ -109,8 +113,8 @@ const { title, description, code } = Astro.props as Props
}
.doc-content ol,
.doc-content ul {
margin-left: 1.25rem;
margin-bottom: 0.75rem;
margin-left: 1.5rem;
margin-bottom: 1.25rem;
}
.doc-content ol {
list-style: decimal;
@@ -119,7 +123,7 @@ const { title, description, code } = Astro.props as Props
list-style: disc;
}
.doc-content li {
margin-bottom: 0.35rem;
margin-bottom: 0.5rem;
}
.doc-content ol ::marker,
.doc-content ul ::marker {
@@ -130,18 +134,18 @@ const { title, description, code } = Astro.props as Props
border: 0;
border-top: 1px solid oklch(0.45 0.04 56 / 0.5);
box-shadow: 0 3px 0 -2px oklch(0.45 0.04 56 / 0.5);
margin: 1.5rem 0;
margin: 2.5rem 0;
}
.doc-content table {
width: 100%;
border-collapse: collapse;
margin-bottom: 1rem;
font-size: 0.8125rem;
margin-bottom: 1.25rem;
font-size: 0.875rem;
}
.doc-content th,
.doc-content td {
border: 1px solid oklch(0.5 0.04 56 / 0.35);
padding: 0.5rem 0.75rem;
padding: 0.625rem 0.875rem;
text-align: left;
vertical-align: top;
}
@@ -149,7 +153,7 @@ const { title, description, code } = Astro.props as Props
font-family: var(--font-heading);
font-weight: 600;
text-transform: uppercase;
font-size: 0.7rem;
font-size: 0.75rem;
letter-spacing: 0.05em;
background: oklch(0.5 0.04 56 / 0.08);
}
-87
View File
@@ -1,87 +0,0 @@
export type Classification = 'СОВ. СЕКРЕТНО' | 'СЕКРЕТНО' | 'ДСП' | 'РАССЕКРЕЧЕНО'
export type Dossier = {
slug: string
code: string
name: string
fullName: string
category: 'ИНВЕНТАРЬ' | 'ПЕРСОНА' | 'ОБЪЕКТ' | 'ДИРЕКТИВА'
classification: Classification
threat: string
summary: string
}
export const DOSSIERS: Dossier[] = [
{
slug: 'lopata-bs-3000',
code: 'ИНВ-001',
name: 'Л.О.П.А.Т.А.',
fullName:
'Локализатор Органических Признаков Анунаков Трансгрессивного Адаптера',
category: 'ИНВЕНТАРЬ',
classification: 'СОВ. СЕКРЕТНО',
threat: 'КАТ. III',
summary:
'Модель БС-3000 (Садово-Боевая). Обнуление маскировочных био-голограмм и принудительное заземление внеземных агентов в полевых условиях.',
},
{
slug: 'subject-ogurec',
code: 'ОБЪ-014',
name: 'СУБЪЕКТ «ОГУРЕЦ»',
fullName: 'Биомаскировочная единица класса «Парниковый»',
category: 'ОБЪЕКТ',
classification: 'СЕКРЕТНО',
threat: 'КАТ. II',
summary:
'Рептилоидный агент, выявленный при инвентаризации теплицы участка №6. Демаскирован при пониженной температуре грунта.',
},
{
slug: 'directive-kompot',
code: 'ДИР-007',
name: 'ДИРЕКТИВА «КОМПОТ»',
fullName: 'Устав полевого противодействия чешуйчатому личному составу',
category: 'ДИРЕКТИВА',
classification: 'ДСП',
threat: 'КАТ. I',
summary:
'Свод обязательных предписаний для дачников-наблюдателей при контакте с предполагаемым агентом планеты Нибиру.',
},
{
slug: 'agent-baba-zina',
code: 'ПЕР-003',
name: 'АГЕНТ «БАБА ЗИНА»',
fullName: 'Старший полевой оператор, участок №3, кооператив «Заря-9»',
category: 'ПЕРСОНА',
classification: 'РАССЕКРЕЧЕНО',
threat: '—',
summary:
'Кавалер ордена Трудовой Грядки. Лично заземлила 14 (четырнадцать) подтверждённых рептилоидных единиц. Личность охраняется.',
},
{
slug: 'object-nibiru',
code: 'ОБЪ-000',
name: 'ПЛАНЕТА НИБИРУ',
fullName: 'Источник трансгрессивной угрозы садоводческим территориям',
category: 'ОБЪЕКТ',
classification: 'СОВ. СЕКРЕТНО',
threat: 'КАТ. IV',
summary:
'Внесистемное тело. Период сближения совпадает с пиком урожайности. Координаты [ДАННЫЕ ИЗЪЯТЫ].',
},
{
slug: 'equipment-vedro',
code: 'ИНВ-022',
name: 'В.Е.Д.Р.О.',
fullName:
'Высокочастотный Экранирующий Дезинтегратор Рептилоидных Оболочек',
category: 'ИНВЕНТАРЬ',
classification: 'СЕКРЕТНО',
threat: 'КАТ. II',
summary:
'Оцинкованный контур-ловушка. Накрывается на голову агента для блокировки телепатического канала с орбитой.',
},
]
export function getDossier(slug: string) {
return DOSSIERS.find((d) => d.slug === slug)
}
+65 -68
View File
@@ -1,125 +1,122 @@
export type RegistryEntry = {
id: string | null
title: string
annotation: string
status: 'open' | 'deleted' | 'restricted' | 'lost' | 'classified' | 'password' | 'danger'
slug?: string
}
id: string | null;
title: string;
annotation: string;
status: "open" | "deleted" | "restricted" | "lost" | "classified" | "password" | "danger";
slug?: string;
};
export const REGISTRY: RegistryEntry[] = [
{
id: 'МДС-ТП-2024',
title: 'Инструкция по боевому применению системы Л.О.П.А.Т.А.',
annotation: 'Пользовательская инструкция по базовому боевому применению системы',
status: 'open',
slug: 'user-manual',
id: "МДС-ТП-2024",
title: "Технический паспорт изделия Л.О.П.А.Т.А. (Модель БС-3000).",
annotation:
"Полное инженерное описание устройства, волнового стального резонатора и диэлектрического березового интерфейса.",
status: "open",
slug: "datasheet",
},
{
id: "МДС-ТП-2024",
title: "Инструкция по боевому применению системы Л.О.П.А.Т.А.",
annotation: "Пользовательская инструкция по базовому боевому применению системы",
status: "open",
slug: "user-manual",
},
{
id: null,
title: 'Боевой устав применения системы Л.О.П.А.Т.А.',
title: "Боевой устав применения системы Л.О.П.А.Т.А.",
annotation:
'Основной тактический документ Сопротивления. Содержит базовые принципы обнуления трансгрессивных адаптеров и 6 фундаментальных шагов ведения полевой демаскировки.',
status: 'deleted',
"Основной тактический документ Сопротивления. Содержит базовые принципы обнуления трансгрессивных адаптеров и 6 фундаментальных шагов ведения полевой демаскировки.",
status: "deleted",
},
{
id: 'МДС-ПП-11',
title: 'Приложение №1: Тактика ближнего боя в ограниченных ионосферных пространствах.',
id: "МДС-ПП-11",
title: "Приложение №1: Тактика ближнего боя в ограниченных ионосферных пространствах.",
annotation:
'Практическое руководство по ликвидации анунаков в замкнутых локациях типа «Лифт», «Офисный коридор» и «Кустарниковая зона».',
status: 'open',
slug: 'appendix-1',
"Практическое руководство по ликвидации анунаков в замкнутых локациях типа «Лифт», «Офисный коридор» и «Кустарниковая зона».",
status: "open",
slug: "appendix-1",
},
{
id: null,
title: 'Приложение №2: Тактика ведения боя в условиях плотной городской застройки (Метод «Двор-Метро»).',
title: "Приложение №2: Тактика ведения боя в условиях плотной городской застройки (Метод «Двор-Метро»).",
annotation:
'Инструкция по нейтрализации замаскированных агентов на асфальтовом и бетонном покрытии. Описывает приём «Искра из-под подошвы» и метод маскировки Л.О.П.А.Т.Ы. под обычный строительный инструмент дорожного рабочего.',
status: 'deleted',
"Инструкция по нейтрализации замаскированных агентов на асфальтовом и бетонном покрытии. Описывает приём «Искра из-под подошвы» и метод маскировки Л.О.П.А.Т.Ы. под обычный строительный инструмент дорожного рабочего.",
status: "deleted",
},
{
id: null,
title: 'Приложение №3: Тактика зимнего противостояния (Протокол «Белая Иллюзия»).',
title: "Приложение №3: Тактика зимнего противостояния (Протокол «Белая Иллюзия»).",
annotation:
'Руководство по ведению боя в условиях отрицательных температур. При низких температурах трансгрессивный адаптер пришельцев начинает сильно греться, выдавая их локацию паром из ушей.',
status: 'deleted',
"Руководство по ведению боя в условиях отрицательных температур. При низких температурах трансгрессивный адаптер пришельцев начинает сильно греться, выдавая их локацию паром из ушей.",
status: "deleted",
},
{
id: null,
title: 'Приложение №4: Тактика ведения боя на воде и в прибрежных зонах (Операция «Чешуя в камышах»).',
title: "Приложение №4: Тактика ведения боя на воде и в прибрежных зонах (Операция «Чешуя в камышах»).",
annotation:
'Анунаки обожают маскироваться под рыбаков или отдыхающих на пляжах, чтобы восстанавливать гидро-баланс. Документ содержит тактику «Весло-Трансформер».',
status: 'deleted',
"Анунаки обожают маскироваться под рыбаков или отдыхающих на пляжах, чтобы восстанавливать гидро-баланс. Документ содержит тактику «Весло-Трансформер».",
status: "deleted",
},
{
id: null,
title: 'Приложение №5: Тактика ведения боя в условиях общественного транспорта (Инструкция «Час Пик»).',
annotation:
'Особенности применения БС-3000 в переполненных автобусах, трамваях и вагонах электричек.',
status: 'deleted',
title: "Приложение №5: Тактика ведения боя в условиях общественного транспорта (Инструкция «Час Пик»).",
annotation: "Особенности применения БС-3000 в переполненных автобусах, трамваях и вагонах электричек.",
status: "deleted",
},
{
id: null,
title: 'Приложение №6: Тактика ночного боя и противодействие тепловизионному зрению (Протокол «Слепое пятно»).',
title: "Приложение №6: Тактика ночного боя и противодействие тепловизионному зрению (Протокол «Слепое пятно»).",
annotation:
'Рептилоиды прекрасно видят в темноте инфракрасный спектр. Документ обучает использованию разогретого стального полотна Л.О.П.А.Т.Ы. в качестве теплового экрана.',
status: 'deleted',
},
{
id: 'МДС-ТП-2024',
title: 'Технический паспорт изделия Л.О.П.А.Т.А. (Модель БС-3000).',
annotation:
'Полное инженерное описание устройства, волнового стального резонатора и диэлектрического березового интерфейса.',
status: 'open',
slug: 'datasheet',
"Рептилоиды прекрасно видят в темноте инфракрасный спектр. Документ обучает использованию разогретого стального полотна Л.О.П.А.Т.Ы. в качестве теплового экрана.",
status: "deleted",
},
{
id: null,
title: 'Памятка по перехвату ментальных IT-сигналов.',
title: "Памятка по перехвату ментальных IT-сигналов.",
annotation:
'Инструкция для гражданских лиц, объясняющая, как отличить системный сбой нано-костюма ящерицы от обычного человеческого переутомления.',
status: 'deleted',
"Инструкция для гражданских лиц, объясняющая, как отличить системный сбой нано-костюма ящерицы от обычного человеческого переутомления.",
status: "deleted",
},
{
id: null,
title: 'Регламент экстренной связи с мобильной группой «Бабушка с лопатой».',
title: "Регламент экстренной связи с мобильной группой «Бабушка с лопатой».",
annotation:
'Описание радиочастотных кодов (Канал 13) и звуковых маркеров для вызова тяжелой дачной артиллерии в зону прорыва.',
status: 'lost',
"Описание радиочастотных кодов (Канал 13) и звуковых маркеров для вызова тяжелой дачной артиллерии в зону прорыва.",
status: "lost",
},
{
id: null,
title: 'Приложение №2: Система распознавания «Свой-Чужой» при контакте с председателями СНТ.',
annotation:
'Статус: Засекречено Советом Земли из-за высокого риска междоусобных войн за чернозём.',
status: 'deleted',
title: "Приложение №2: Система распознавания «Свой-Чужой» при контакте с председателями СНТ.",
annotation: "Статус: Засекречено Советом Земли из-за высокого риска междоусобных войн за чернозём.",
status: "deleted",
},
{
id: null,
title: 'Схемы скрытого ношения БС-3000 в городских условиях под видом элементов складного самоката или моноколеса.',
annotation:
'Статус: Ожидает верификации инженерным отделом на предмет электромагнитной совместимости.',
status: 'restricted',
title: "Схемы скрытого ношения БС-3000 в городских условиях под видом элементов складного самоката или моноколеса.",
annotation: "Статус: Ожидает верификации инженерным отделом на предмет электромагнитной совместимости.",
status: "restricted",
},
{
id: null,
title: 'Стенограмма допроса пленного Анунака 4-го ранга, пойманного на краже элитных семян томатов «Бычье сердце».',
annotation: 'Статус: Файл засекречен Межгалактическим Комитетом Рептилоидов',
status: 'classified',
title: "Стенограмма допроса пленного Анунака 4-го ранга, пойманного на краже элитных семян томатов «Бычье сердце».",
annotation: "Статус: Файл засекречен Межгалактическим Комитетом Рептилоидов",
status: "classified",
},
{
id: null,
title: 'Сценарий операции «ДАЧНЫЙ СЕЗОН»',
title: "Сценарий операции «ДАЧНЫЙ СЕЗОН»",
annotation:
'Описание сценария глобального перехвата и заземления ночного десанта тарелок Нибиру с помощью одновременного удара плашмя 10 000 операторов Л.О.П.А.Т.',
status: 'password',
"Описание сценария глобального перехвата и заземления ночного десанта тарелок Нибиру с помощью одновременного удара плашмя 10 000 операторов Л.О.П.А.Т.",
status: "password",
},
{
id: null,
title: 'Химический анализ зелёной люминесцентной субстанции (хладагента).',
title: "Химический анализ зелёной люминесцентной субстанции (хладагента).",
annotation:
'Статус: Заблокировано Минздравом. Документ содержит незацензуренные рецепты приготовления противоядия на основе рассола.',
status: 'danger',
"Статус: Заблокировано Минздравом. Документ содержит незацензуренные рецепты приготовления противоядия на основе рассола.",
status: "danger",
},
]
];
export const OPEN_SLUGS = REGISTRY.filter((e) => e.status === 'open').map((e) => e.slug!)
export const OPEN_SLUGS = REGISTRY.filter((e) => e.status === "open").map((e) => e.slug!);
+15 -17
View File
@@ -1,9 +1,9 @@
---
import BaseLayout from '../layouts/base.astro'
import SiteHeader from '../components/SiteHeader.astro'
import SiteFooter from '../components/SiteFooter.astro'
import Perforation from '../components/Perforation.astro'
import OverlayStamp from '../components/OverlayStamp.astro'
import OverlayStamp from "../components/OverlayStamp.astro";
import Perforation from "../components/Perforation.astro";
import SiteFooter from "../components/SiteFooter.astro";
import SiteHeader from "../components/SiteHeader.astro";
import BaseLayout from "../layouts/base.astro";
---
<BaseLayout title="Доступ запрещён // Архив ДНТ-7">
@@ -11,7 +11,9 @@ import OverlayStamp from '../components/OverlayStamp.astro'
<SiteHeader />
<div class="banner-classified border-y border-foreground/30">
<div class="mx-auto flex max-w-4xl items-center justify-between gap-4 px-4 py-1.5 text-[0.65rem] font-700 uppercase tracking-[0.2em] sm:px-6">
<div
class="mx-auto flex max-w-4xl items-center justify-between gap-4 px-4 py-1.5 text-[0.65rem] font-700 uppercase tracking-[0.2em] sm:px-6"
>
<span>СОВ. СЕКРЕТНО</span>
<span class="hidden sm:inline">Гриф особой важности</span>
<span>Доступ закрыт</span>
@@ -20,7 +22,7 @@ import OverlayStamp from '../components/OverlayStamp.astro'
<main class="mx-auto flex max-w-4xl px-4 py-24 sm:px-6">
<article class="paper relative mx-auto w-full max-w-lg -rotate-[0.3deg] p-10 text-center">
<span class="tape -top-3 left-1/2 -translate-x-1/2 rotate-2" aria-hidden="true" />
<span class="tape -top-3 left-1/2 -translate-x-1/2 rotate-2" aria-hidden="true"></span>
<div class="pointer-events-none absolute right-6 top-6 rotate-[12deg]">
<OverlayStamp class="text-3xl sm:text-4xl">ЗАПРЕЩЕНО</OverlayStamp>
@@ -37,24 +39,20 @@ import OverlayStamp from '../components/OverlayStamp.astro'
<hr class="rule rule-red mx-auto my-6 w-32" />
<p class="text-sm leading-relaxed text-foreground/90">
Запрашиваемый документ находится под грифом особой важности и не
подлежит разглашению лицам без ментального допуска 3-го уровня.
Запрашиваемый документ находится под грифом особой важности и не подлежит разглашению лицам без ментального
допуска 3-го уровня.
</p>
<p class="mt-3 text-sm leading-relaxed text-foreground/90">
Ожидайте следующую партию рассекреченных документов. Сроки
рассекречивания будут объявлены дополнительным циркуляром.
Ожидайте следующую партию рассекреченных документов. Сроки рассекречивания будут объявлены дополнительным
циркуляром.
</p>
<div class="mt-8">
<span class="stamp stamp-skew mx-auto inline-flex px-4 py-2 text-sm">
Доступ запрещён
</span>
<span class="stamp stamp-skew mx-auto inline-flex px-4 py-2 text-sm"> Доступ запрещён </span>
</div>
<p class="mt-8 text-[0.65rem] uppercase tracking-wider text-muted-foreground">
Форма А-13 · Хранить вечно
</p>
<p class="mt-8 text-[0.65rem] uppercase tracking-wider text-muted-foreground">Форма А-13 · Хранить вечно</p>
</article>
</main>
+1 -1
View File
@@ -16,7 +16,7 @@ code: МДС-ТП-2024
## 1. ТЕХНИЧЕСКИЕ ХАРАКТЕРИСТИКИ
| Параметр | Значение / Описание |
| --- | --- |
| -------------------- | -------------------------------------------------------------------------------- |
| Интерфейс управления | Деревянный цилиндрический черенок (берёза/ясень, класс защиты от телепатии IP68) |
| Рабочий орган | Сверхпрочная углеродистая сталь с анти-чешуйчатым напылением |
| Радиус поражения | Длина черенка + длина вытянутой руки патриота Земли (приблизительно 1.5–2 метра) |
+71 -59
View File
@@ -1,33 +1,33 @@
---
import BaseLayout from '../layouts/base.astro'
import SiteHeader from '../components/SiteHeader.astro'
import SiteFooter from '../components/SiteFooter.astro'
import Stamp from '../components/Stamp.astro'
import OverlayStamp from '../components/OverlayStamp.astro'
import Perforation from '../components/Perforation.astro'
import { REGISTRY } from '../lib/registry'
import OverlayStamp from "../components/OverlayStamp.astro";
import Perforation from "../components/Perforation.astro";
import SiteFooter from "../components/SiteFooter.astro";
import SiteHeader from "../components/SiteHeader.astro";
import Stamp from "../components/Stamp.astro";
import BaseLayout from "../layouts/base.astro";
import { REGISTRY } from "../lib/registry";
const statusLabel: Record<string, string> = {
open: 'ОТКРЫТ',
deleted: 'ДАННЫЕ УДАЛЕНЫ',
restricted: 'ДОСТУП ОГРАНИЧЕН',
lost: 'ДАННЫЕ ПОТЕРЯНЫ',
classified: 'ЗАСЕКРЕЧЕНО',
password: 'ДОСТУП ПО ПАРОЛЮ',
danger: 'ОПАСНОСТЬ ЗАРАЖЕНИЯ',
}
open: "ОТКРЫТ",
deleted: "ДАННЫЕ УДАЛЕНЫ",
restricted: "ДОСТУП ОГРАНИЧЕН",
lost: "ДАННЫЕ ПОТЕРЯНЫ",
classified: "ЗАСЕКРЕЧЕНО",
password: "ДОСТУП ПО ПАРОЛЮ",
danger: "ОПАСНОСТЬ ЗАРАЖЕНИЯ",
};
const statusColor: Record<string, string> = {
open: 'text-primary',
deleted: 'text-muted-foreground opacity-60',
restricted: 'text-muted-foreground opacity-70',
lost: 'text-muted-foreground opacity-50',
classified: 'text-primary',
password: 'text-foreground',
danger: 'text-primary',
}
open: "text-primary",
deleted: "text-muted-foreground opacity-60",
restricted: "text-muted-foreground opacity-70",
lost: "text-muted-foreground opacity-50",
classified: "text-primary",
password: "text-foreground",
danger: "text-primary",
};
const tilts = ['-0.6deg', '0.5deg', '-0.4deg']
const tilts = ["-0.6deg", "0.5deg", "-0.4deg"];
---
<BaseLayout title="РЕЕСТР ДОКУМЕНТОВ // Архив ДНТ-7">
@@ -35,7 +35,9 @@ const tilts = ['-0.6deg', '0.5deg', '-0.4deg']
<SiteHeader />
<div class="banner-classified border-y border-foreground/30">
<div class="mx-auto flex max-w-5xl items-center justify-between gap-4 px-4 py-1.5 text-[0.65rem] font-700 uppercase tracking-[0.2em] sm:px-6">
<div
class="mx-auto flex max-w-5xl items-center justify-between gap-4 px-4 py-1.5 text-[0.65rem] font-700 uppercase tracking-[0.2em] sm:px-6"
>
<span>Сов. Секретно</span>
<span class="hidden sm:inline">Реестр МДС</span>
<span>Хранить вечно</span>
@@ -45,8 +47,8 @@ const tilts = ['-0.6deg', '0.5deg', '-0.4deg']
<main class="mx-auto max-w-5xl px-4 py-10 sm:px-6">
<!-- Hero -->
<section class="paper relative mb-12 -rotate-[0.4deg] p-6 sm:p-10">
<span class="tape -top-3 left-10 rotate-3" aria-hidden="true" />
<span class="tape -top-3 right-12 -rotate-2" aria-hidden="true" />
<span class="tape -top-3 left-10 rotate-3" aria-hidden="true"></span>
<span class="tape -top-3 right-12 -rotate-2" aria-hidden="true"></span>
<div class="pointer-events-none absolute right-4 top-4 sm:right-8 sm:top-8">
<img
@@ -61,13 +63,14 @@ const tilts = ['-0.6deg', '0.5deg', '-0.4deg']
<p class="font-mono text-xs uppercase tracking-[0.3em] text-muted-foreground">
Межгалактическое Дачное Сопротивление · Архив ДНТ-7
</p>
<h1 class="mt-3 max-w-2xl text-balance font-heading text-3xl font-700 uppercase leading-[0.95] tracking-tight sm:text-5xl">
<h1
class="mt-3 max-w-2xl text-balance font-heading text-3xl font-700 uppercase leading-[0.95] tracking-tight sm:text-5xl"
>
Реестр документов МДС
</h1>
<p class="mt-4 max-w-xl text-pretty text-sm leading-relaxed text-foreground/90">
Рассекреченный реестр документов Межгалактического Дачного Сопротивления.
Статус базы данных: доступ ограничен. Требуется ментальный допуск 3-го уровня
и шапочка из фольги марки А1.
Рассекреченный реестр документов Межгалактического Дачного Сопротивления. Статус базы данных: доступ
ограничен. Требуется ментальный допуск 3-го уровня и шапочка из фольги марки А1.
</p>
<div class="mt-6 flex flex-wrap items-center gap-3">
@@ -87,9 +90,7 @@ const tilts = ['-0.6deg', '0.5deg', '-0.4deg']
<section class="mb-12">
<div class="mb-6 flex items-end justify-between">
<div>
<h2 class="font-heading text-xl font-700 uppercase tracking-wide">
Открытые дела
</h2>
<h2 class="font-heading text-xl font-700 uppercase tracking-wide">Открытые дела</h2>
<hr class="rule rule-red mt-2 w-32" />
</div>
<p class="font-mono text-[0.65rem] uppercase tracking-wider text-muted-foreground">
@@ -98,16 +99,15 @@ const tilts = ['-0.6deg', '0.5deg', '-0.4deg']
</div>
<div class="grid grid-cols-1 gap-4 sm:grid-cols-3">
{REGISTRY.filter((e) => e.status === 'open').map((e, i) => (
{
REGISTRY.filter((e) => e.status === "open").map((e, i) => (
<a
href={`/docs/${e.slug}`}
class="paper group relative flex flex-col gap-2 p-5 transition-all duration-200 hover:-translate-y-1 hover:shadow-[0_26px_50px_-22px_rgba(40,25,15,0.7)]"
style={{ rotate: tilts[i] }}
>
<span class="tape -top-3 left-1/2 -translate-x-1/2 -rotate-2" aria-hidden="true" />
<p class="font-heading text-[0.7rem] font-600 uppercase tracking-wider text-primary">
{e.id}
</p>
<p class="font-heading text-[0.7rem] font-600 uppercase tracking-wider text-primary">{e.id}</p>
<h3 class="font-heading text-base font-700 uppercase leading-tight tracking-tight transition-colors group-hover:text-primary">
{e.title}
</h3>
@@ -118,7 +118,8 @@ const tilts = ['-0.6deg', '0.5deg', '-0.4deg']
</span>
</div>
</a>
))}
))
}
</div>
</section>
@@ -126,9 +127,7 @@ const tilts = ['-0.6deg', '0.5deg', '-0.4deg']
<section>
<div class="mb-6 flex items-end justify-between">
<div>
<h2 class="font-heading text-xl font-700 uppercase tracking-wide">
Полный реестр
</h2>
<h2 class="font-heading text-xl font-700 uppercase tracking-wide">Полный реестр</h2>
<hr class="rule mt-2 w-40" />
</div>
<p class="font-mono text-[0.65rem] uppercase tracking-wider text-muted-foreground">
@@ -137,40 +136,53 @@ const tilts = ['-0.6deg', '0.5deg', '-0.4deg']
</div>
<div class="space-y-3">
{REGISTRY.map((entry, i) => {
const isOpen = entry.status === 'open'
const href = isOpen ? `/docs/${entry.slug}` : '/404'
{
REGISTRY.map((entry, i) => {
const isOpen = entry.status === "open";
const href = isOpen ? `/docs/${entry.slug}` : undefined;
const Tag = isOpen ? "a" : "div";
return (
<a
<Tag
href={href}
class:list={[
'paper flex items-start justify-between gap-4 px-4 py-3 text-sm transition-all',
isOpen && 'hover:-translate-y-0.5 hover:shadow-[0_12px_30px_-16px_rgba(40,25,15,0.5)]',
"flex items-start justify-between gap-4 px-4 py-3 text-sm transition-all",
isOpen
? "paper border-l-4 border-l-primary hover:-translate-y-0.5 hover:shadow-[0_12px_30px_-16px_rgba(40,25,15,0.5)]"
: "border border-border/30 bg-card/50 opacity-50 cursor-default",
]}
style={{ rotate: i % 2 === 0 ? '-0.2deg' : '0.2deg' }}
style={{ rotate: i % 2 === 0 ? "-0.2deg" : "0.2deg" }}
>
<div class="min-w-0 flex-1">
<span class="font-mono text-[0.65rem] uppercase tracking-wider text-muted-foreground">
{entry.id ? `[${entry.id}]` : '[ДАННЫЕ УДАЛЕНЫ]'}
<span
class:list={[
"font-mono text-[0.65rem] uppercase tracking-wider",
isOpen ? "text-primary" : "text-muted-foreground",
]}
>
{entry.id ? `[${entry.id}]` : "[ДАННЫЕ УДАЛЕНЫ]"}
</span>
<p class="mt-0.5 font-heading text-sm font-600 uppercase leading-snug tracking-tight">
<p
class:list={[
"mt-0.5 font-heading text-sm font-600 uppercase leading-snug tracking-tight",
!isOpen && "line-through",
]}
>
{entry.title}
</p>
<p class="mt-1 text-xs leading-relaxed text-muted-foreground">
{entry.annotation}
</p>
<p class="mt-1 text-xs leading-relaxed text-muted-foreground">{entry.annotation}</p>
</div>
<span
class:list={[
'shrink-0 font-heading text-[0.6rem] font-600 uppercase tracking-wider',
"shrink-0 font-heading text-[0.65rem] font-600 uppercase tracking-wider",
statusColor[entry.status],
]}
>
{statusLabel[entry.status]}
</span>
</a>
)
})}
</Tag>
);
})
}
</div>
</section>
+34 -19
View File
@@ -1,11 +1,11 @@
@import 'tailwindcss';
@import "tailwindcss";
@custom-variant dark (&:is(.dark *));
@theme inline {
--font-heading: 'Oswald', sans-serif;
--font-sans: 'IBM Plex Mono', monospace;
--font-mono: 'IBM Plex Mono', monospace;
--font-heading: "Oswald", sans-serif;
--font-sans: "IBM Plex Mono", monospace;
--font-mono: "IBM Plex Mono", monospace;
--color-sidebar-ring: var(--sidebar-ring);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
@@ -91,20 +91,25 @@
body {
@apply bg-background text-foreground;
background-image:
radial-gradient(
130% 120% at 50% 0%,
transparent 55%,
oklch(0.3 0.04 52 / 0.12) 100%
),
radial-gradient(130% 120% at 50% 0%, transparent 55%, oklch(0.3 0.04 52 / 0.12) 100%),
radial-gradient(oklch(0.3 0.03 52 / 0.05) 1px, transparent 1.4px),
radial-gradient(oklch(0.3 0.03 52 / 0.04) 1px, transparent 1.4px),
linear-gradient(180deg, oklch(0.91 0.03 80), oklch(0.88 0.03 76));
background-size: 100% 100%, 16px 16px, 22px 22px, 100% 100%;
background-position: 0 0, 0 0, 8px 11px, 0 0;
background-size:
100% 100%,
16px 16px,
22px 22px,
100% 100%;
background-position:
0 0,
0 0,
8px 11px,
0 0;
background-attachment: fixed;
}
html {
@apply font-mono;
font-size: 18px;
}
}
@@ -117,12 +122,11 @@
position: relative;
background-color: var(--card);
background-image:
linear-gradient(
oklch(0.5 0.03 56 / 0.05) 1px,
transparent 1px
),
linear-gradient(oklch(0.5 0.03 56 / 0.05) 1px, transparent 1px),
radial-gradient(oklch(0.3 0.03 52 / 0.04) 1px, transparent 1.3px);
background-size: 100% 30px, 18px 18px;
background-size:
100% 30px,
18px 18px;
border: 1px solid oklch(0.5 0.04 56 / 0.35);
box-shadow:
0 1px 0 oklch(1 0 0 / 0.4) inset,
@@ -167,7 +171,8 @@
box-shadow: inset 0 0 0 1.5px var(--c);
opacity: 0.78;
mix-blend-mode: multiply;
-webkit-mask-image: radial-gradient(oklch(0 0 0) 60%, transparent 62%),
-webkit-mask-image:
radial-gradient(oklch(0 0 0) 60%, transparent 62%),
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='80' height='40'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1.4 1.1'/%3E%3C/filter%3E%3Crect width='80' height='40' filter='url(%23n)'/%3E%3C/svg%3E");
-webkit-mask-composite: source-over;
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='80' height='40'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1.4 1.1'/%3E%3C/filter%3E%3Crect width='80' height='40' filter='url(%23n)'/%3E%3C/svg%3E");
@@ -202,8 +207,7 @@
}
.banner-classified {
background:
repeating-linear-gradient(
background: repeating-linear-gradient(
45deg,
oklch(0.42 0.16 30),
oklch(0.42 0.16 30) 14px,
@@ -213,3 +217,14 @@
color: var(--primary-foreground);
}
}
.doc-content {
& p {
margin-top: 0.5rem;
}
& h1,
h2 {
margin-top: 2rem;
margin-bottom: 1rem;
}
}