Files
2026-hypn0-site/hypn0/templates/blog/detail.html
T
2026-09-09 23:37:19 +03:00

308 lines
18 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{% extends '_base.html' %}
{% load static %}
{% block PAGE_TITLE %}{{ post.s_title|striptags }} | Хроники гипноза HypnoSVG{% endblock %}
{% block META_TITLE %}{{ post.s_title|striptags }} — HypnoSVG{% endblock %}
{% block META_DESCRIPTION %}{% if post.s_teaser %}{{ post.s_teaser|striptags|truncatechars:160 }}{% else %}Статья из хроник гипноза HypnoSVG: {{ post.s_title|striptags }}{% endif %}{% endblock %}
{% block OG_TITLE %}{{ post.s_title|striptags }} | HypnoSVG{% endblock %}
{% block OG_DESCRIPTION %}{% if post.s_teaser %}{{ post.s_teaser|striptags|truncatechars:200 }}{% else %}Статья из хроник гипноза HypnoSVG: {{ post.s_title|striptags }}{% endif %}{% endblock %}
{% block OG_IMAGE %}{% if post.f_cover_img %}{{ request.scheme }}://{{ request.get_host }}{{ post.f_cover_img.url }}{% elif post.k_item and post.k_item.file_svg %}{{ request.scheme }}://{{ request.get_host }}{{ post.k_item.file_svg.url }}{% else %}{% static 'img/og-hypn0-default.png' %}{% endif %}{% endblock %}
{% block CANONICAL %}{{ request.scheme }}://{{ request.get_host }}{{ post.get_absolute_url }}{% endblock %}
{% block EXTRA_LD_JSON %},
{
"@type": "Article",
"headline": "{{ post.s_title|striptags|escapejs }}",
"description": "{{ post.s_teaser|striptags|escapejs }}",
"datePublished": "{{ post.d_published_at|date:'c' }}",
"dateModified": "{{ post.d_updated_at|date:'c' }}",
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "{{ request.scheme }}://{{ request.get_host }}{{ post.get_absolute_url }}"
}
}
{% endblock EXTRA_LD_JSON %}
{% block CONTENT %}
<article class="mx-auto space-y-10">
<!-- Навигационная полоса / Хлебные крошки -->
<nav class="flex items-center gap-2 text-xs font-bold uppercase tracking-wider text-stone-500 dark:text-stone-400">
<a href="{% url 'hypn0_site:blog_feed' %}"
class="inline-flex items-center gap-1.5 hover:text-stone-900 dark:hover:text-stone-100 transition-colors border-0">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"/>
</svg>
<span>Все депеши</span>
</a>
{% if series_parent %}
<span class="text-stone-300 dark:text-zinc-700">/</span>
<a href="{{ series_parent.get_absolute_url }}" class="hover:text-purple-600 dark:hover:text-purple-400 transition-colors border-0">
{{ series_parent.s_title|striptags|truncatechars:25 }}
</a>
{% endif %}
</nav>
<!-- Серия: индикатор цикла (если пост является частью серии) -->
{% if series_parent %}
<div class="bg-purple-500/10 dark:bg-purple-950/30 border border-purple-500/20 rounded-2xl p-4 sm:p-5 flex flex-col sm:flex-row sm:items-center justify-between gap-3">
<div class="flex items-center gap-3">
<span class="w-2.5 h-2.5 rounded-full bg-purple-500 animate-pulse shrink-0"></span>
<div class="text-xs">
<span class="text-stone-500 dark:text-stone-400">Материал входит в серию:</span>
<a href="{{ series_parent.get_absolute_url }}" class="font-bold text-purple-700 dark:text-purple-300 hover:underline border-0 ml-1">
{{ series_parent.s_title|safe }}
</a>
</div>
</div>
<span class="text-[11px] font-mono text-purple-600 dark:text-purple-400 shrink-0">
Глава {{ post.i_order }}
</span>
</div>
{% endif %}
<!-- Заголовок, метаданные и превью статьи (двухколоночный блок) -->
<header class="space-y-6">
<!-- Метаданные статьи: бейджи слева, дата-время справа -->
<div class="flex flex-wrap items-center justify-between gap-3 border-b border-stone-200/60 dark:border-zinc-800/80 pb-3">
<div class="flex flex-wrap items-center gap-2">
<span class="inline-flex items-center gap-1.5 px-3 py-1 rounded-full text-xs font-bold uppercase tracking-wider bg-purple-500/15 text-purple-700 dark:text-purple-300 border border-purple-500/30">
Хроники гипноза
</span>
{% if post.k_item %}
<a href="{% url 'hypn0_site:gallery_detail' post.k_item.s_hash_id %}" class="inline-flex items-center gap-1.5 px-3 py-1 rounded-full text-xs font-mono font-bold bg-emerald-500/15 text-emerald-700 dark:text-emerald-300 border border-emerald-500/30 hover:bg-emerald-500/25 transition-colors border-0">
<span class="w-1.5 h-1.5 rounded-full bg-emerald-500"></span>
Аддитивная картина «Галереи Транса»: #{{ post.k_item.s_hash_id }}
</a>
{% endif %}
</div>
<time datetime="{{ post.d_published_at|date:'c' }}" class="font-mono text-xs text-stone-500 dark:text-stone-400">
{{ post.d_published_at|date:'d E 30y, H:i:s' }}
</time>
</div>
<!-- Тизер-превью слева (1/4), Заголовок + Тизер справа (3/4) -->
<div class="grid grid-cols-1 md:grid-cols-4 gap-6 items-start">
<!-- Тизер-превью слева (1/4) -->
<div class="md:col-span-1 w-full">
{% if post.f_cover_img %}{# ЕСТЬ ТИЗЕР-КАРТИНКА И ПОКАЗЫВАЕМ ЕË #}
<div class="aspect-square sm:aspect-[4/3] md:aspect-square rounded-2xl overflow-hidden border border-stone-200 dark:border-zinc-800 shadow-md bg-stone-100 dark:bg-zinc-900">
<img src="{{ post.f_cover_img.url }}"
alt="{{ post.s_title|striptags }}"
class="w-full h-full object-cover">
</div>
{% else %}{# НЕТ ТИЗЕР-КАРТИНКИ И ПОКАЗЫВАЕМ ЗАГЛУШКУ #}
<div class="aspect-square sm:aspect-[4/3] md:aspect-square rounded-2xl border border-dashed border-stone-300 dark:border-zinc-700 bg-stone-100/40 dark:bg-zinc-900/40 flex flex-col items-center justify-center p-3 text-stone-400 dark:text-stone-600 text-center">
<img src="{% static 'img/brain-slug.svg' %}" alt="Гипножаба" class="w-10 h-10 opacity-40 mb-1">{# <-- СЮДА ДЕФОЛТНУЮ КАРТИНКУ #}
<span class="text-[10px] font-mono uppercase tracking-wider">Тут ничего не нарисовано</span>{# <-- А ПОСЛЕ ЭТО УБРАТЬ #}
</div>
{% endif %}
</div>
<!-- Заголовок + Тизер справа (3/4) -->
<div class="md:col-span-3">
<h1 class="text-3xl sm:text-4xl lg:text-5xl font-black tracking-tight text-stone-900 dark:text-stone-100 leading-tight border-l-1 border-purple-500 border-dotted pl-6">
{{ post.s_title|safe }}
</h1>
<!-- Лид / Тизер статьи -->
{% if post.s_teaser %}
<div class="text-base sm:text-lg text-stone-600 dark:text-stone-300 leading-relaxed font-sans border-l-1 border-purple-500 border-dotted pl-6 py-6 bg-stone-100/50 dark:bg-zinc-900/50 rounded-r-2xl ">
{{ post.s_teaser|safe }}
</div>
{% endif %}
</div>
</div>
</header>
<!-- БЛОК СВЯЗАННОГО SVG (если статья рассказывает о конкретной генерации) -->
{% if post.k_item %}
<section class="bg-gradient-to-br from-purple-500/10 via-stone-100/80 to-emerald-500/10 dark:from-purple-950/30 dark:via-zinc-900/90 dark:to-emerald-950/20 rounded-3xl border border-purple-300/80 dark:border-purple-900/50 p-6 sm:p-8 shadow-xl space-y-6 backdrop-blur-md">
<div class="flex flex-wrap items-center justify-between gap-3 border-b border-purple-200/60 dark:border-purple-900/40 pb-4">
<div class="flex items-center gap-2.5">
<div class="w-3 h-3 rounded-full bg-emerald-500 animate-pulse"></div>
<h2 class="text-base font-bold uppercase tracking-wider text-stone-900 dark:text-stone-100">
Связанная SVG-матрица: {{ post.k_item.s_title }}
</h2>
</div>
<span class="text-xs font-mono px-2.5 py-0.5 rounded-full bg-emerald-500/20 text-emerald-700 dark:text-emerald-300 border border-emerald-500/30">
{{ post.k_item.get_i_level_display }}
</span>
</div>
<div class="flex flex-col md:flex-row items-center gap-6">
<!-- Интерактивное полотно картины -->
<div class="w-full md:w-1/2 aspect-square rounded-2xl overflow-hidden border border-stone-200/80 dark:border-zinc-700/80 bg-stone-950 shadow-inner flex items-center justify-center p-2">
{% if active_svg %}
<div class="w-full h-full flex items-center justify-center pointer-events-auto">
{{ active_svg|safe }}
</div>
{% elif post.k_item.file_svg %}
<img src="{{ post.k_item.file_svg.url }}" alt="{{ post.k_item.s_title }}" class="max-w-full max-h-full object-contain">
{% endif %}
</div>
<!-- Метаданные генерации и действия -->
<div class="w-full md:w-1/2 space-y-4 text-xs font-mono">
<div class="space-y-2 bg-white/60 dark:bg-zinc-800/60 p-4 rounded-xl border border-stone-200/60 dark:border-zinc-700/60 text-stone-700 dark:text-stone-300">
<div class="flex justify-between">
<span class="opacity-70">Хэш волновой матрицы:</span>
<span class="font-bold text-purple-600 dark:text-purple-400">#{{ post.k_item.s_hash_id }}</span>
</div>
{% if svg_stats.total_oscillators %}
<div class="flex justify-between">
<span class="opacity-70">Осцилляций в сетке:</span>
<span class="font-bold">{{ svg_stats.total_oscillators }}</span>
</div>
{% endif %}
{% if svg_stats.viewbox %}
<div class="flex justify-between">
<span class="opacity-70">Пространство viewBox:</span>
<span class="font-bold">{{ svg_stats.viewbox }}</span>
</div>
{% endif %}
<div class="flex justify-between">
<span class="opacity-70">Признание сообщества:</span>
<span class="font-bold text-emerald-600 dark:text-emerald-400">{{ post.k_item.i_likes_count }} лайков</span>
</div>
</div>
<div class="flex flex-wrap gap-2.5 pt-2">
<a href="{% url 'hypn0_site:gallery_detail' post.k_item.s_hash_id %}"
class="inline-flex items-center gap-1.5 px-4 py-2.5 rounded-xl text-xs font-bold bg-purple-600 hover:bg-purple-700 text-white transition-all shadow-md hover:scale-105 active:scale-95 border-0">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"/>
</svg>
<span>В галерею</span>
</a>
<a href="{% url 'hypn0_site:gallery_download' post.k_item.s_hash_id %}"
class="inline-flex items-center gap-1.5 px-4 py-2.5 rounded-xl text-xs font-bold bg-stone-100 hover:bg-stone-200 dark:bg-zinc-800 dark:hover:bg-zinc-700 text-stone-700 dark:text-stone-200 transition-all shadow-sm border border-stone-200 dark:border-zinc-700 border-0">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"/>
</svg>
<span>Скачать SVG</span>
</a>
</div>
</div>
</div>
</section>
{% endif %}
<!-- Основной контент статьи -->
<div class="prose max-w-none font-sans text-base sm:text-lg">
{{ post.s_content|safe }}
</div>
<!-- РАЗДЕЛ СЕРИИ: список глав (если статья является родительской подборкой/серией) -->
{% if series_posts and not series_parent %}
<section class="space-y-4 pt-8 border-t border-stone-200 dark:border-zinc-800">
<div class="flex items-center gap-3">
<div class="w-3 h-3 rounded-full bg-purple-500"></div>
<h2 class="text-xl font-bold uppercase tracking-wider text-stone-900 dark:text-stone-100">
Материалы и главы этого цикла
</h2>
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
{% for child in series_posts %}
<div class="bg-stone-100/70 dark:bg-zinc-900/70 rounded-2xl border border-stone-200 dark:border-zinc-800 p-4 space-y-2 hover:border-purple-400 dark:hover:border-purple-600 transition-colors">
<div class="flex items-center justify-between text-[11px] font-mono text-stone-400">
<span class="font-bold text-purple-600 dark:text-purple-400">Глава {{ child.i_order }}</span>
<time datetime="{{ child.d_published_at|date:'c' }}">{{ child.d_published_at|date:'d E Y' }}</time>
</div>
<h3 class="font-bold text-sm text-stone-900 dark:text-stone-100">
<a href="{{ child.get_absolute_url }}" class="hover:text-purple-600 dark:hover:text-purple-400 transition-colors border-0">
{{ child.s_title|safe }}
</a>
</h3>
{% if child.s_teaser %}
<p class="text-xs text-stone-600 dark:text-stone-400 line-clamp-2">
{{ child.s_teaser|striptags }}
</p>
{% endif %}
</div>
{% endfor %}
</div>
</section>
{% endif %}
<!-- НАВИГАЦИЯ ВПЕРЕД / НАЗАД -->
<footer class="pt-8 border-t border-stone-200 dark:border-zinc-800 space-y-6">
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
<!-- Предыдущая статья -->
{% if prev_post %}
<a href="{{ prev_post.get_absolute_url }}"
class="group flex flex-col p-5 rounded-2xl bg-stone-100/70 dark:bg-zinc-900/70 border border-stone-200 dark:border-zinc-800 hover:border-purple-400 dark:hover:border-purple-600 transition-all shadow-sm border-0">
<span class="text-xs font-mono text-stone-400 dark:text-stone-500 mb-1 inline-flex items-center gap-1 group-hover:text-purple-600 transition-colors">
<svg class="w-3.5 h-3.5 transition-transform group-hover:-translate-x-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"/>
</svg>
{% if series_parent %}Предыдущая глава цикла{% else %}Предыдущая депеша{% endif %}
</span>
<span class="font-bold text-sm text-stone-900 dark:text-stone-100 line-clamp-2">
{{ prev_post.s_title|safe }}
</span>
</a>
{% else %}
<div class="p-5 rounded-2xl bg-stone-100/30 dark:bg-zinc-900/30 border border-stone-200/40 dark:border-zinc-800/40 opacity-40">
<span class="text-xs font-mono text-stone-400 block mb-1">
{% if series_parent %}Первая глава цикла{% else %}Начало хроник гипноза{% endif %}
</span>
<span class="font-bold text-sm text-stone-500 dark:text-stone-400">
Нет предшествующих записей
</span>
</div>
{% endif %}
<!-- Следующая статья -->
{% if next_post %}
<a href="{{ next_post.get_absolute_url }}"
class="group flex flex-col items-end text-right p-5 rounded-2xl bg-stone-100/70 dark:bg-zinc-900/70 border border-stone-200 dark:border-zinc-800 hover:border-purple-400 dark:hover:border-purple-600 transition-all shadow-sm border-0">
<span class="text-xs font-mono text-stone-400 dark:text-stone-500 mb-1 inline-flex items-center gap-1 group-hover:text-purple-600 transition-colors">
{% if series_parent %}Следующая глава цикла{% else %}Следующая депеша{% endif %}
<svg class="w-3.5 h-3.5 transition-transform group-hover:translate-x-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/>
</svg>
</span>
<span class="font-bold text-sm text-stone-900 dark:text-stone-100 line-clamp-2">
{{ next_post.s_title|safe }}
</span>
</a>
{% else %}
<div class="flex flex-col items-end text-right p-5 rounded-2xl bg-stone-100/30 dark:bg-zinc-900/30 border border-stone-200/40 dark:border-zinc-800/40 opacity-40">
<span class="text-xs font-mono text-stone-400 block mb-1">
{% if series_parent %}Финальная глава цикла{% else %}Край ноосферы{% endif %}
</span>
<span class="font-bold text-sm text-stone-500 dark:text-stone-400">
Свежие депеши еще материализуются
</span>
</div>
{% endif %}
</div>
<!-- Центральная кнопка возврата в блог -->
<div class="text-center pt-2">
<a href="{% url 'hypn0_site:blog_feed' %}"
class="inline-flex items-center gap-2 px-5 py-2.5 rounded-xl text-xs font-bold uppercase tracking-wider bg-stone-100 hover:bg-stone-200 dark:bg-zinc-800 dark:hover:bg-zinc-700 text-stone-700 dark:text-stone-300 transition-all border border-stone-200 dark:border-zinc-700 border-0">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 10h16M4 14h16M4 18h16"/>
</svg>
<span>Все статьи в хрониках</span>
</a>
</div>
</footer>
</article>
{% endblock CONTENT %}