feat: update design from ref

This commit is contained in:
2026-06-11 12:16:34 +05:00
parent a5be6d7552
commit 2a209247d3
38 changed files with 1792 additions and 57 deletions
+57
View File
@@ -0,0 +1,57 @@
---
import type { Dossier } from '../lib/dossiers'
import Stamp from './Stamp.astro'
interface Props {
d: Dossier
rotate?: string
}
const { d, rotate } = Astro.props as Props
const classColor: Record<string, string> = {
'СОВ. СЕКРЕТНО': 'text-primary',
'СЕКРЕТНО': 'stamp-ink',
'ДСП': 'stamp-ink',
'РАССЕКРЕЧЕНО': 'stamp-ink opacity-60',
}
---
<a
href={`/dossier/${d.slug}`}
style={{ rotate }}
class="paper group relative flex flex-col gap-3 p-5 transition-all duration-200 hover:-translate-y-1 hover:rotate-0 hover:shadow-[0_26px_50px_-22px_rgba(40,25,15,0.7)]"
>
<span class="tape -top-3 left-1/2 -translate-x-1/2 -rotate-2" aria-hidden="true" />
<div class="flex items-start justify-between gap-2">
<div>
<p class="font-mono text-[0.65rem] uppercase tracking-widest text-muted-foreground">
Дело № {d.code}
</p>
<p class="mt-0.5 font-heading text-[0.7rem] uppercase tracking-wider text-primary">
{d.category}
</p>
</div>
<Stamp class={`px-1.5 py-0.5 text-[0.55rem] ${classColor[d.classification] ?? ''}`}>
{d.classification}
</Stamp>
</div>
<h3 class="font-heading text-xl font-700 uppercase leading-none tracking-tight transition-colors group-hover:text-primary">
{d.name}
</h3>
<p class="text-xs italic leading-snug text-muted-foreground">
{d.fullName}
</p>
<p class="text-sm leading-relaxed text-foreground/90">{d.summary}</p>
<div class="mt-auto flex items-center justify-between border-t border-dashed border-border pt-3">
<span class="font-mono text-[0.65rem] uppercase tracking-wider text-muted-foreground">
Угроза: <span class="text-foreground">{d.threat}</span>
</span>
<span class="font-heading text-[0.7rem] font-600 uppercase tracking-wider text-primary opacity-0 transition-opacity group-hover:opacity-100">
Открыть дело →
</span>
</div>
</a>
+15
View File
@@ -0,0 +1,15 @@
---
interface Props {
label?: string
value?: string
}
const { label, value } = Astro.props as Props
---
<div class="grid grid-cols-1 gap-1 border-b border-dashed border-border py-3 sm:grid-cols-[200px_1fr] sm:gap-4">
<dt class="font-heading text-xs font-600 uppercase tracking-wider text-muted-foreground">
{label}
</dt>
<dd class="text-sm leading-relaxed text-foreground" set:html={value}></dd>
</div>
+18
View File
@@ -0,0 +1,18 @@
---
interface Props {
children?: any
class?: string
}
const { children, class: className } = Astro.props as Props
---
<span
aria-hidden="true"
class:list={[
'stamp-overlay pointer-events-none select-none px-4 py-2 font-heading text-2xl sm:text-4xl',
className,
]}
>
{children}
</span>
+21
View File
@@ -0,0 +1,21 @@
---
interface Props {
class?: string
}
const { class: className } = Astro.props as Props
---
<div
aria-hidden="true"
class:list={[
'flex h-4 w-full items-center justify-between overflow-hidden px-2 opacity-60',
className,
]}
>
{
Array.from({ length: 60 }).map(() => (
<span class="h-1.5 w-1.5 shrink-0 rounded-full bg-background shadow-[inset_0_1px_2px_rgba(0,0,0,0.35)]" />
))
}
</div>
+9
View File
@@ -0,0 +1,9 @@
---
interface Props {
children?: any
}
const { children } = Astro.props as Props
---
<span class="redacted px-1">{children}</span>
+17
View File
@@ -0,0 +1,17 @@
---
interface Props {
children?: any
index: string
}
const { children, index } = Astro.props as Props
---
<h2 class="mb-4 flex items-baseline gap-3 font-heading text-lg font-700 uppercase tracking-wide">
<span class="flex h-7 min-w-7 items-center justify-center bg-primary px-1.5 text-sm text-primary-foreground">
{index}
</span>
<span class="flex-1 border-b border-foreground/30 pb-1">
{children}
</span>
</h2>
+16
View File
@@ -0,0 +1,16 @@
<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">
<p>
© <span class="text-foreground">Дачно-Наблюдательный Трибунал №7</span>
· Кооператив «Заря-9»
</p>
<p>Форма А-13 · Хранить вечно · Не выносить за периметр</p>
</div>
<p class="mt-4 max-w-2xl text-[0.7rem] leading-relaxed text-muted-foreground">
Все материалы являются художественным вымыслом. Любое совпадение с
реальными грядками, соседями и небесными телами случайно. Разглашение
преследуется лишением компоста.
</p>
</div>
</footer>
+27
View File
@@ -0,0 +1,27 @@
<header class="sticky top-0 z-30 border-b border-foreground/25 bg-card/85 backdrop-blur-sm shadow-[0_2px_12px_-8px_rgba(40,25,15,0.6)]">
<div class="mx-auto flex max-w-5xl flex-col gap-4 px-4 py-4 sm:flex-row sm:items-center sm:justify-between sm:px-6">
<a href="/" class="flex items-center gap-3">
<img
src="/emblem.png"
alt="Эмблема Трибунала"
width="52"
height="52"
class="h-12 w-12 mix-blend-multiply"
/>
<div class="leading-tight">
<p class="font-heading text-base font-700 uppercase tracking-wide sm:text-lg">
Архив ДНТ-7
</p>
<p class="text-[0.65rem] uppercase tracking-widest text-muted-foreground">
Дачно-Наблюдательный Трибунал
</p>
</div>
</a>
<nav class="flex flex-wrap items-center gap-x-5 gap-y-1 font-heading text-xs font-600 uppercase tracking-wider">
<a href="/" class="relative text-foreground/80 transition-colors hover:text-primary">Картотека</a>
<a href="/dossier/directive-kompot" class="relative text-foreground/80 transition-colors hover:text-primary">Уставы</a>
<a href="/dossier/lopata-bs-3000" class="relative text-foreground/80 transition-colors hover:text-primary">Инвентарь</a>
<a href="/protocol" class="relative text-foreground/80 transition-colors hover:text-primary">Протокол</a>
</nav>
</div>
</header>
+21
View File
@@ -0,0 +1,21 @@
---
interface Props {
children?: any
class?: string
skew?: boolean
variant?: 'red' | 'ink'
}
const { children, class: className, skew = true, variant = 'red' } = Astro.props as Props
---
<span
class:list={[
'stamp px-2 py-1 text-[0.65rem] sm:text-xs',
variant === 'ink' && 'stamp-ink',
skew && 'stamp-skew',
className,
]}
>
{children}
</span>
+29
View File
@@ -0,0 +1,29 @@
---
import '../styles/globals.css'
interface Props {
title: string
description?: string
}
const { title, description } = Astro.props as Props
---
<!doctype html>
<html lang="ru" class="bg-background">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>{title}</title>
{description && <meta name="description" content={description} />}
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600;700&family=Oswald:wght@400;500;600;700&display=swap" rel="stylesheet" />
</head>
<body class="font-mono antialiased">
<slot />
</body>
</html>
+205
View File
@@ -0,0 +1,205 @@
---
import BaseLayout from './base.astro'
import SiteHeader from '../components/SiteHeader.astro'
import SiteFooter from '../components/SiteFooter.astro'
import OverlayStamp from '../components/OverlayStamp.astro'
import FieldRow from '../components/FieldRow.astro'
import Perforation from '../components/Perforation.astro'
import { DOSSIERS, getDossier } from '../lib/dossiers'
interface Props {
title: string
fullName?: string
code?: string
category?: string
classification?: string
threat?: string
hasBlueprint?: boolean
hasPhoto?: boolean
fields?: { label: string; value: string }[]
}
const frontmatter = Astro.props as Props
const slug = Astro.url.pathname.replace('/dossier/', '').replace('/', '')
const dossier = getDossier(slug)
const allDossiers = DOSSIERS
---
<BaseLayout title={`${frontmatter.title} // Архив ДНТ-7`} description={frontmatter.fullName}>
<div class="min-h-screen">
<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">
<span>{frontmatter.classification}</span>
<span class="hidden sm:inline">Дело № {frontmatter.code}</span>
<span>Экз. № 1</span>
</div>
</div>
<main class="mx-auto max-w-4xl px-4 py-8 sm:px-6">
<a
href="/"
class="font-heading text-xs font-600 uppercase tracking-wider text-muted-foreground hover:text-primary"
>
← Вернуться в картотеку
</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" />
<div class="pointer-events-none absolute right-3 top-4 rotate-[9deg] sm:right-8 sm:top-10">
<OverlayStamp class="text-xl sm:text-3xl">
{frontmatter.classification}
</OverlayStamp>
</div>
<header class="pb-5">
<p class="font-mono text-[0.7rem] uppercase tracking-[0.25em] text-muted-foreground">
{frontmatter.category} · Дело № {frontmatter.code} · Угроза {frontmatter.threat}
</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">
{frontmatter.title}
</h1>
<p class="mt-3 max-w-2xl text-sm italic leading-relaxed text-muted-foreground">
{frontmatter.fullName}
</p>
<hr class="rule rule-red mt-5" />
</header>
<section class="mt-2">
<dl>
{frontmatter.fields?.map((f) => (
<FieldRow label={f.label} value={f.value} />
))}
</dl>
</section>
{frontmatter.hasBlueprint && (
<figure class="paper paper-strong mt-8 p-3">
<img
src="/blueprint-lopata.png"
alt={`Технический чертёж изделия ${frontmatter.title}`}
width="1200"
height="800"
class="h-auto w-full mix-blend-multiply"
/>
<figcaption class="mt-2 border-t border-dashed border-border pt-2 text-center font-mono text-[0.65rem] uppercase tracking-wider text-muted-foreground">
Рис. 1 — Чертёж общего вида · ГОСТ-садовый 12-86
</figcaption>
</figure>
)}
{frontmatter.hasPhoto && (
<figure class="paper paper-strong mt-8 max-w-sm rotate-1 p-2">
<img
src="/classified-photo.png"
alt="Рассекреченный фотоматериал"
width="600"
height="600"
class="h-auto w-full grayscale"
/>
<figcaption class="mt-2 border-t border-dashed border-border pt-2 font-mono text-[0.6rem] uppercase tracking-wider text-muted-foreground">
Фотоматериал · участок №6 · 03:14
</figcaption>
</figure>
)}
<div class="mt-10 prose-custom">
<slot />
</div>
<footer class="mt-12 grid grid-cols-1 gap-6 border-t border-dashed border-border pt-6 sm:grid-cols-2">
<div>
<p class="text-[0.7rem] uppercase tracking-wider text-muted-foreground">
Утвердил
</p>
<p class="mt-3 font-heading text-base font-600">
Председатель Трибунала
</p>
<p class="mt-1 border-b border-foreground/50 pb-1 font-mono text-sm text-muted-foreground">
подпись: [ИЗЪЯТО]
</p>
</div>
<div class="flex items-start justify-end">
<img
src="/emblem.png"
alt=""
width="90"
height="90"
class="h-20 w-20 rotate-6 opacity-80 mix-blend-multiply"
/>
</div>
</footer>
</article>
<section class="mt-10">
<h2 class="mb-1 font-heading text-lg font-700 uppercase tracking-wide">
См. также
</h2>
<hr class="rule mb-5 w-40" />
<div class="grid grid-cols-1 gap-3 sm:grid-cols-2">
{allDossiers.filter((d) => d.slug !== slug).slice(0, 4).map((d) => (
<a
href={`/dossier/${d.slug}`}
class="paper flex items-center justify-between px-3 py-2.5 text-sm transition-all hover:-translate-y-0.5 hover:text-primary"
>
<span class="font-heading uppercase tracking-wide">{d.name}</span>
<span class="font-mono text-[0.65rem] text-muted-foreground">{d.code}</span>
</a>
))}
</div>
</section>
<div class="mt-12">
<Perforation />
</div>
</main>
<SiteFooter />
</div>
</BaseLayout>
<style>
.prose-custom h2 {
font-family: var(--font-heading);
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.05em;
font-size: 1.125rem;
margin-bottom: 1rem;
padding-bottom: 0.25rem;
border-bottom: 1px solid oklch(0.45 0.04 56 / 0.3);
}
.prose-custom h2 + * {
margin-top: 0;
}
.prose-custom p,
.prose-custom li {
font-size: 0.875rem;
line-height: 1.625;
color: oklch(0.28 0.03 52 / 0.9);
}
.prose-custom p {
margin-bottom: 0.75rem;
}
.prose-custom ol,
.prose-custom ul {
margin-left: 1rem;
margin-bottom: 0.75rem;
}
.prose-custom ol {
list-style: decimal;
}
.prose-custom ul {
list-style: disc;
}
.prose-custom li {
margin-bottom: 0.25rem;
}
.prose-custom ol ::marker,
.prose-custom ul ::marker {
color: var(--primary);
font-weight: 700;
}
</style>
-32
View File
@@ -1,32 +0,0 @@
---
const { frontmatter } = Astro.props;
---
<!doctype html>
<html lang="ru">
<head>
<meta charset="UTF-8" />
<title>{frontmatter.title}</title>
<style>
body {
font-family: sans-serif;
background: #fafafa;
color: #333;
}
main {
max-width: 800px;
margin: 0 auto;
padding: 2rem;
}
</style>
</head>
<body>
<header>
<a href="/">Главная</a>
</header>
<main>
<slot />
</main>
</body>
</html>
+87
View File
@@ -0,0 +1,87 @@
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)
}
+24
View File
@@ -0,0 +1,24 @@
---
layout: ../../layouts/dossier.astro
title: АГЕНТ «БАБА ЗИНА»
fullName: Старший полевой оператор, участок №3, кооператив «Заря-9»
code: ПЕР-003
category: ПЕРСОНА
classification: РАССЕКРЕЧЕНО
threat: "—"
fields:
- label: Позывной
value: "Агент «Баба Зина»"
- label: Должность
value: "Старший полевой оператор"
- label: Участок
value: "№3, кооператив «Заря-9»"
- label: Заслуги
value: "Орден Трудовой Грядки I степени"
- label: Подтверждённых заземлений
value: "14 (четырнадцать)"
---
## 1. Характеристика
Образцовый полевой оператор. Лично разработала метод демаскировки «соль в три щепоти». Передаёт опыт молодым дачникам. Личность охраняется, фотоматериалы <span class="redacted px-1">ДАННЫЕ ИЗЪЯТЫ</span> в целях безопасности оператора и его теплицы.
+29
View File
@@ -0,0 +1,29 @@
---
layout: ../../layouts/dossier.astro
title: ДИРЕКТИВА «КОМПОТ»
fullName: Устав полевого противодействия чешуйчатому личному составу
code: ДИР-007
category: ДИРЕКТИВА
classification: ДСП
threat: КАТ. I
fields:
- label: Обозначение
value: "Директива «Компот»"
- label: Тип документа
value: "Устав полевого противодействия"
- label: Действует с
value: "01.05.1986"
- label: Гриф
value: "Для служебного пользования"
---
## I. Общие положения
Настоящий устав определяет обязательный порядок действий дачника-наблюдателя при установлении контакта с предполагаемым агентом планеты Нибиру на территории садоводческого товарищества. Незнание устава не освобождает от дежурства по сторожке.
## II. Обязанности наблюдателя
1. Сохранять бдительность в часы пик урожайности.
2. Иметь при себе исправный инвентарь (см. дело ИНВ-001).
3. Не вступать с агентом в переговоры о рассаде.
4. Докладывать о любом немигающем соседе незамедлительно.
+26
View File
@@ -0,0 +1,26 @@
---
layout: ../../layouts/dossier.astro
title: В.Е.Д.Р.О.
fullName: Высокочастотный Экранирующий Дезинтегратор Рептилоидных Оболочек
code: ИНВ-022
category: ИНВЕНТАРЬ
classification: СЕКРЕТНО
threat: КАТ. II
fields:
- label: Наименование
value: В.Е.Д.Р.О.
- label: Полное название
value: Высокочастотный Экранирующий Дезинтегратор Рептилоидных Оболочек
- label: Материал
value: "Сталь оцинкованная, контур-ловушка"
- label: Объём
value: "12 л (стандарт кооператива)"
---
## 1. Назначение
Оцинкованный контур-ловушка для блокировки телепатического канала агента с орбитой. Накрывается на голову локализованной единицы, создавая экранирующую клетку Фарадея кустарного исполнения.
## 2. Применение в связке
Используется совместно с изделием Л.О.П.А.Т.А. (дело ИНВ-001): сперва заземление, затем экранирование. Эффективность связки подтверждена агентом «Баба Зина».
+46
View File
@@ -0,0 +1,46 @@
---
layout: ../../layouts/dossier.astro
title: Л.О.П.А.Т.А.
fullName: Локализатор Органических Признаков Анунаков Трансгрессивного Адаптера
code: ИНВ-001
category: ИНВЕНТАРЬ
classification: СОВ. СЕКРЕТНО
threat: КАТ. III
hasBlueprint: true
fields:
- label: Наименование изделия
value: Л.О.П.А.Т.А.
- label: Индекс
value: "Модель БС-3000 / Садово-Боевая"
- label: Полное инж. название
value: Локализатор Органических Признаков Анунаков Трансгрессивного Адаптера
- label: Изготовитель
value: "Артель «Острый Штык», цех №4"
- label: Масса снаряжённая
value: "2,7 кг ± 0,3 кг"
- label: Заточка
value: "Двухсторонняя, угол 23°"
- label: Ресурс
value: "не менее 400 (четырёхсот) заземлений"
---
## 1. Назначение
Изделие предназначено для обнуления маскировочных био-голограмм, принудительного заземления внеземных агентов и демаскировки чешуйчатого личного состава в полевых условиях. Допускается применение по прямому хозяйственному назначению (вскапывание грунта) в целях сохранения легенды оператора.
## 2. Принцип действия
Рабочее полотно изделия выполнено из заземлённого сплава «ЧУГ-7». При плотном контакте с поверхностью агента происходит срыв голографической оболочки и отвод паразитных нибируанских токов в грунт через черенок-токоотвод.
Эффект демаскировки достигается за 1 (один) уверенный удар плашмя. Повторные удары наносятся до полного проявления чешуи либо до признания агентом своей внеземной природы.
## 3. Порядок применения
1. Убедиться в отсутствии посторонних дачников на смежных участках.
2. Принять стойку «Прополка боевая»: ноги на ширину грядки, черенок у пояса.
3. При первых признаках маскировки (немигающий взгляд, любовь к солнцу, неприятие соли) — нанести заземляющий удар.
4. Зафиксировать результат в журнале формы Б-2 и доложить старшему по кооперативу.
## 4. Меры безопасности
Запрещается заземлять агента при влажной обуви оператора. Запрещается оставлять изделие в борще. Хранить в сарае под охраной кота. При появлении на полотне зелёного свечения — изделие подлежит сдаче в артель для перезаточки и <span class="redacted px-1">ДАННЫЕ ИЗЪЯТЫ</span>.
+26
View File
@@ -0,0 +1,26 @@
---
layout: ../../layouts/dossier.astro
title: ПЛАНЕТА НИБИРУ
fullName: Источник трансгрессивной угрозы садоводческим территориям
code: ОБЪ-000
category: ОБЪЕКТ
classification: СОВ. СЕКРЕТНО
threat: КАТ. IV
fields:
- label: Обозначение
value: "Планета Нибиру"
- label: Класс угрозы
value: "КАТ. IV (трансгрессивная)"
- label: Период сближения
value: "совпадает с пиком урожайности"
- label: Координаты
value: <span class="redacted px-1">ДАННЫЕ ИЗЪЯТЫ</span>
---
## 1. Описание объекта
Внесистемное небесное тело, признанное источником трансгрессивной угрозы садоводческим территориям. По данным наблюдений с водонапорной башни, сближение объекта вызывает аномальный рост сорняков и активизацию замаскированных агентов.
## 2. Рекомендации
В период сближения усилить дежурства, проверять рассаду на чешую, держать инвентарь заточенным. Дальнейшие сведения изъяты по грифу «Сов. Секретно».
+29
View File
@@ -0,0 +1,29 @@
---
layout: ../../layouts/dossier.astro
title: СУБЪЕКТ «ОГУРЕЦ»
fullName: Биомаскировочная единица класса «Парниковый»
code: ОБЪ-014
category: ОБЪЕКТ
classification: СЕКРЕТНО
threat: КАТ. II
hasPhoto: true
fields:
- label: Обозначение
value: "Субъект «Огурец»"
- label: Класс
value: "Биомаскировочная единица «Парниковый»"
- label: Место выявления
value: "Теплица, участок №6"
- label: Состояние
value: "Локализован, заземлён"
---
## 1. Обстоятельства выявления
Субъект обнаружен при плановой инвентаризации теплицы. Демаскирован при понижении температуры грунта ниже +8°C, при котором маскировочная оболочка теряет тургор и проявляется чешуйчатая структура. Реагировал на соль крайне нехарактерным для овоща образом.
## 2. Признаки внеземного происхождения
- Отсутствие семян при наличии идеальной формы.
- Поворот к наблюдателю независимо от положения солнца.
- Слабый запах озона и <span class="redacted px-1">ДАННЫЕ ИЗЪЯТЫ</span>.
+113 -14
View File
@@ -1,17 +1,116 @@
---
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 DossierCard from '../components/DossierCard.astro'
import { DOSSIERS } from '../lib/dossiers'
const tilts = ['-0.6deg', '0.5deg', '-0.4deg', '0.7deg', '-0.5deg', '0.4deg']
---
---
<BaseLayout title="АРХИВ ДНТ-7 // Дачно-Наблюдательный Трибунал" description="Рассекреченный архив Дачно-Наблюдательного Трибунала №7. Документы, инструкции и уставы по противодействию рептилоидным агентам планеты Нибиру.">
<div class="min-h-screen">
<SiteHeader />
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>Astro</title>
</head>
<body>
<h1>LOPATA</h1>
</body>
</html>
<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">
<span>Сов. Секретно</span>
<span class="hidden sm:inline">Экз. № 1 из 3</span>
<span>Хранить вечно</span>
</div>
</div>
<main class="mx-auto max-w-5xl px-4 py-10 sm:px-6">
<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" />
<div class="pointer-events-none absolute right-4 top-4 sm:right-8 sm:top-8">
<img
src="/emblem.png"
alt=""
width="120"
height="120"
class="h-20 w-20 opacity-90 mix-blend-multiply sm:h-28 sm:w-28"
/>
</div>
<p class="font-mono text-xs uppercase tracking-[0.3em] text-muted-foreground">
Союз Садоводческих Кооперативов · Отдел «Грядка»
</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">
Архив Дачно-Наблюдательного Трибунала №7
</h1>
<p class="mt-4 max-w-xl text-pretty text-sm leading-relaxed text-foreground/90">
Рассекреченный свод документов, инструкций и уставов по
противодействию рептилоидным агентам планеты{' '}
<span class="font-600 text-primary">Нибиру</span> на территориях
садоводческих товариществ. Допуск согласно форме А-13.
</p>
<div class="mt-6 flex flex-wrap items-center gap-3">
<Stamp>Рассекречено · 06.07.2026</Stamp>
<Stamp variant="ink" skew={false}>Подлежит изучению</Stamp>
<span class="font-mono text-[0.65rem] uppercase tracking-wider text-muted-foreground">
Регистр. № ДНТ-7/04-1986
</span>
</div>
<div class="pointer-events-none absolute -bottom-3 right-6 rotate-[8deg] sm:right-16">
<OverlayStamp>Архивъ · ДНТ-7</OverlayStamp>
</div>
</section>
<section class="mb-12 grid grid-cols-2 gap-4 sm:grid-cols-4">
{[
{ k: 'Дел в картотеке', v: '147' },
{ k: 'Заземлено агентов', v: '38' },
{ k: 'Активных участков', v: '9' },
{ k: 'Уровень тревоги', v: 'III' },
].map((s, i) => (
<div
key={s.k}
class="paper px-4 py-5 text-center"
style={{ rotate: tilts[i] }}
>
<p class="font-heading text-3xl font-700 text-primary">
{s.v}
</p>
<p class="mt-1 text-[0.65rem] uppercase tracking-wider text-muted-foreground">
{s.k}
</p>
</div>
))}
</section>
<section>
<div class="mb-8 flex items-end justify-between">
<div>
<h2 class="font-heading text-2xl font-700 uppercase tracking-wide">
Картотека дел
</h2>
<hr class="rule rule-red mt-2 w-48" />
</div>
<p class="font-mono text-[0.65rem] uppercase tracking-wider text-muted-foreground">
Опись · лист 1
</p>
</div>
<div class="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3">
{DOSSIERS.map((d, i) => (
<DossierCard d={d} rotate={tilts[i % tilts.length]} />
))}
</div>
</section>
<div class="mt-12">
<Perforation />
</div>
</main>
<SiteFooter />
</div>
</BaseLayout>
+128
View File
@@ -0,0 +1,128 @@
---
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 SectionTitle from '../components/SectionTitle.astro'
import Perforation from '../components/Perforation.astro'
const STEPS = [
{
n: '01',
t: 'Обнаружение',
d: 'Зафиксировать признаки маскировки: немигающий взгляд, любовь к солнцу, неприятие соли, идеальная рассада без труда.',
},
{
n: '02',
t: 'Доклад',
d: 'Сообщить старшему по кооперативу через условный сигнал (три удара по бочке с водой).',
},
{
n: '03',
t: 'Локализация',
d: 'Применить изделие Л.О.П.А.Т.А. (ИНВ-001) для заземления. Соблюдать меры безопасности.',
},
{
n: '04',
t: 'Экранирование',
d: 'Накрыть изделием В.Е.Д.Р.О. (ИНВ-022) для блокировки канала связи с орбитой.',
},
{
n: '05',
t: 'Регистрация',
d: 'Внести запись в журнал формы Б-2. Присвоить делу номер. Хранить вечно.',
},
]
---
<BaseLayout title="Протокол противодействия // Архив ДНТ-7" description="Единый полевой протокол Дачно-Наблюдательного Трибунала №7">
<div class="min-h-screen">
<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">
<span>Для служебного пользования</span>
<span class="hidden sm:inline">Форма Б-2</span>
<span>Изучить под роспись</span>
</div>
</div>
<main class="mx-auto max-w-4xl px-4 py-8 sm:px-6">
<article class="paper relative -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" />
<div class="pointer-events-none absolute right-4 top-4 sm:right-8 sm:top-10">
<img
src="/emblem.png"
alt=""
width="90"
height="90"
class="h-16 w-16 opacity-80 mix-blend-multiply sm:h-20 sm:w-20"
/>
</div>
<header class="pb-5">
<p class="font-mono text-[0.7rem] uppercase tracking-[0.25em] text-muted-foreground">
Единый полевой протокол · ДНТ-7
</p>
<h1 class="mt-3 max-w-xl text-balance font-heading text-3xl font-700 uppercase leading-[0.95] tracking-tight sm:text-5xl">
Протокол противодействия
</h1>
<div class="mt-4 flex flex-wrap gap-3">
<Stamp>Обязательно к исполнению</Stamp>
<Stamp variant="ink" skew={false}>Ред. 1986</Stamp>
</div>
<hr class="rule rule-red mt-5" />
</header>
<section class="mt-8">
<SectionTitle index="§">Порядок действий</SectionTitle>
<ol class="space-y-4">
{STEPS.map((s, i) => (
<li
key={s.n}
class="paper flex gap-4 p-4"
style={{ rotate: i % 2 === 0 ? '-0.4deg' : '0.4deg' }}
>
<span class="font-heading text-3xl font-700 leading-none text-primary">
{s.n}
</span>
<div>
<h3 class="font-heading text-base font-600 uppercase tracking-wide">
{s.t}
</h3>
<p class="mt-1 text-sm leading-relaxed text-foreground/90">
{s.d}
</p>
</div>
</li>
))}
</ol>
</section>
<section class="mt-10">
<SectionTitle index="!">Памятка наблюдателю</SectionTitle>
<div class="grid grid-cols-1 gap-4 sm:grid-cols-3">
{[
'Соль — табельное средство демаскировки.',
'Инвентарь держать заточенным и заземлённым.',
'О немигающих соседях докладывать немедленно.',
].map((p) => (
<p
key={p}
class="paper border-l-4 border-l-primary p-3 text-sm leading-relaxed"
>
{p}
</p>
))}
</div>
</section>
</article>
<div class="mt-12">
<Perforation />
</div>
</main>
<SiteFooter />
</div>
</BaseLayout>
-6
View File
@@ -1,6 +0,0 @@
---
layout: ../layouts/lopata.astro
title: "Моя кастомная страница"
---
# СИСТЕМА Л.О.П.А.Т.А.
+215
View File
@@ -0,0 +1,215 @@
@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;
--color-sidebar-ring: var(--sidebar-ring);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
--color-sidebar-accent: var(--sidebar-accent);
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
--color-sidebar-primary: var(--sidebar-primary);
--color-sidebar-foreground: var(--sidebar-foreground);
--color-sidebar: var(--sidebar);
--color-chart-5: var(--chart-5);
--color-chart-4: var(--chart-4);
--color-chart-3: var(--chart-3);
--color-chart-2: var(--chart-2);
--color-chart-1: var(--chart-1);
--color-ring: var(--ring);
--color-input: var(--input);
--color-border: var(--border);
--color-destructive: var(--destructive);
--color-accent-foreground: var(--accent-foreground);
--color-accent: var(--accent);
--color-muted-foreground: var(--muted-foreground);
--color-muted: var(--muted);
--color-secondary-foreground: var(--secondary-foreground);
--color-secondary: var(--secondary);
--color-primary-foreground: var(--primary-foreground);
--color-primary: var(--primary);
--color-popover-foreground: var(--popover-foreground);
--color-popover: var(--popover);
--color-card-foreground: var(--card-foreground);
--color-card: var(--card);
--color-foreground: var(--foreground);
--color-background: var(--background);
--color-stamp: var(--stamp);
--color-ink: var(--ink);
--color-ink-soft: var(--ink-soft);
--radius-sm: calc(var(--radius) * 0.6);
--radius-md: calc(var(--radius) * 0.8);
--radius-lg: var(--radius);
--radius-xl: calc(var(--radius) * 1.4);
}
:root {
--background: oklch(0.9 0.028 78);
--foreground: oklch(0.32 0.03 52);
--card: oklch(0.945 0.024 84);
--card-foreground: oklch(0.32 0.03 52);
--popover: oklch(0.945 0.024 84);
--popover-foreground: oklch(0.32 0.03 52);
--primary: oklch(0.47 0.16 30);
--primary-foreground: oklch(0.95 0.022 88);
--secondary: oklch(0.86 0.03 78);
--secondary-foreground: oklch(0.34 0.03 52);
--muted: oklch(0.87 0.026 80);
--muted-foreground: oklch(0.5 0.028 56);
--accent: oklch(0.47 0.16 30);
--accent-foreground: oklch(0.95 0.022 88);
--destructive: oklch(0.47 0.16 30);
--border: oklch(0.56 0.035 58 / 0.45);
--input: oklch(0.56 0.035 58 / 0.45);
--ring: oklch(0.47 0.16 30);
--stamp: oklch(0.46 0.17 30);
--ink: oklch(0.32 0.03 52);
--ink-soft: oklch(0.5 0.028 56);
--chart-1: oklch(0.47 0.16 30);
--chart-2: oklch(0.5 0.02 60);
--chart-3: oklch(0.4 0.02 55);
--chart-4: oklch(0.6 0.05 80);
--chart-5: oklch(0.3 0.02 55);
--radius: 0.125rem;
--sidebar: oklch(0.9 0.022 84);
--sidebar-foreground: oklch(0.32 0.03 52);
--sidebar-primary: oklch(0.47 0.16 30);
--sidebar-primary-foreground: oklch(0.95 0.022 88);
--sidebar-accent: oklch(0.86 0.03 78);
--sidebar-accent-foreground: oklch(0.34 0.03 52);
--sidebar-border: oklch(0.56 0.035 58 / 0.45);
--sidebar-ring: oklch(0.47 0.16 30);
}
@layer base {
* {
@apply border-border;
}
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(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-attachment: fixed;
}
html {
@apply font-mono;
}
}
@layer utilities {
.font-heading {
font-family: var(--font-heading);
}
.paper {
position: relative;
background-color: var(--card);
background-image:
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;
border: 1px solid oklch(0.5 0.04 56 / 0.35);
box-shadow:
0 1px 0 oklch(1 0 0 / 0.4) inset,
0 18px 40px -24px oklch(0.25 0.04 52 / 0.55),
0 2px 6px -3px oklch(0.25 0.04 52 / 0.3);
}
.paper-strong {
background-color: oklch(0.5 0.04 56 / 0.06);
}
.tape {
position: absolute;
height: 1.6rem;
width: 6.5rem;
background: oklch(0.78 0.06 92 / 0.55);
box-shadow: 0 1px 4px oklch(0.25 0.04 52 / 0.25);
backdrop-filter: blur(0.5px);
}
.rule {
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);
}
.rule-red {
border-top-color: var(--primary);
box-shadow: 0 3px 0 -2px var(--primary);
}
.stamp {
--c: var(--stamp);
display: inline-flex;
align-items: center;
border: 2.5px solid var(--c);
color: var(--c);
text-transform: uppercase;
letter-spacing: 0.1em;
font-weight: 700;
border-radius: 3px;
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%),
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");
mask-mode: luminance;
}
.stamp-skew {
transform: rotate(-7deg);
}
.stamp-ink {
--c: var(--ink-soft);
}
.stamp-overlay {
color: var(--stamp);
border: 4px solid var(--stamp);
opacity: 0.22;
mix-blend-mode: multiply;
text-transform: uppercase;
font-weight: 700;
letter-spacing: 0.12em;
border-radius: 6px;
}
.redacted {
background: var(--ink);
color: transparent;
user-select: none;
border-radius: 1px;
box-shadow: 0 0 1px 1px oklch(0.3 0.03 52 / 0.4);
}
.banner-classified {
background:
repeating-linear-gradient(
45deg,
oklch(0.42 0.16 30),
oklch(0.42 0.16 30) 14px,
oklch(0.38 0.15 30) 14px,
oklch(0.38 0.15 30) 28px
);
color: var(--primary-foreground);
}
}