Update UI and migrations, fix dockerfile
This commit is contained in:
@@ -0,0 +1,431 @@
|
||||
@font-face {
|
||||
font-family: "Roboto Condensed";
|
||||
src: url("../fonts/roboto-condensed-cyrillic-400.woff2") format("woff2");
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Roboto Condensed";
|
||||
src: url("../fonts/roboto-condensed-cyrillic-700.woff2") format("woff2");
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
:root {
|
||||
color-scheme: dark;
|
||||
--bg: #090c0d;
|
||||
--surface: #101415;
|
||||
--surface-strong: #151a1b;
|
||||
--text: #eceee8;
|
||||
--muted: #9ba19b;
|
||||
--faint: #686f6b;
|
||||
--border: #29302e;
|
||||
--border-strong: #3a423f;
|
||||
--olive: #a5ad62;
|
||||
--red: #df4a40;
|
||||
--max: 1240px;
|
||||
--gutter: 24px;
|
||||
--font: "Roboto Condensed", "Arial Narrow", Arial, sans-serif;
|
||||
}
|
||||
|
||||
* { box-sizing: border-box; }
|
||||
|
||||
html { background: var(--bg); scroll-behavior: smooth; }
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
min-width: 320px;
|
||||
background: var(--bg);
|
||||
color: var(--text);
|
||||
font-family: var(--font);
|
||||
font-size: 18px;
|
||||
line-height: 1.55;
|
||||
letter-spacing: 0;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
body::before {
|
||||
content: "";
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
opacity: .22;
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120' viewBox='0 0 120 120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.08'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
a { color: inherit; text-decoration: none; }
|
||||
a:hover { color: var(--olive); }
|
||||
img, video { display: block; max-width: 100%; }
|
||||
button, input { font: inherit; letter-spacing: 0; }
|
||||
|
||||
:focus-visible { outline: 2px solid var(--olive); outline-offset: 4px; }
|
||||
|
||||
.skip-link {
|
||||
position: fixed;
|
||||
z-index: 100;
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
transform: translateY(-160%);
|
||||
padding: 10px 14px;
|
||||
background: var(--text);
|
||||
color: var(--bg);
|
||||
}
|
||||
.skip-link:focus { transform: none; }
|
||||
|
||||
.site-header {
|
||||
position: sticky;
|
||||
z-index: 20;
|
||||
top: 0;
|
||||
border-bottom: 1px solid var(--border);
|
||||
background: rgba(9, 12, 13, .96);
|
||||
backdrop-filter: blur(12px);
|
||||
}
|
||||
|
||||
.header-inner {
|
||||
width: min(var(--max), calc(100% - var(--gutter) * 2));
|
||||
min-height: 76px;
|
||||
margin: 0 auto;
|
||||
display: grid;
|
||||
grid-template-columns: 170px 1fr auto;
|
||||
align-items: center;
|
||||
gap: 32px;
|
||||
}
|
||||
|
||||
.brand {
|
||||
display: inline-flex;
|
||||
width: fit-content;
|
||||
align-items: center;
|
||||
gap: 11px;
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
line-height: .95;
|
||||
}
|
||||
.brand img { width: 42px; height: 42px; border: 1px solid var(--border-strong); }
|
||||
|
||||
.main-nav { display: flex; justify-content: center; align-self: stretch; gap: 38px; }
|
||||
.main-nav .nav { display: contents; margin: 0; padding: 0; list-style: none; }
|
||||
.main-nav .nav li { display: contents; }
|
||||
.nav-dropdown { position: relative; display: flex; align-items: center; }
|
||||
.nav-dropdown-toggle { display: inline-flex; height: 100%; align-items: center; gap: 8px; padding: 0; border: 0; background: transparent; color: var(--muted); cursor: pointer; }
|
||||
.nav-dropdown-toggle:hover, .nav-dropdown-toggle[aria-expanded="true"] { color: var(--text); }
|
||||
.nav-dropdown-icon { width: 7px; height: 7px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: translateY(-2px) rotate(45deg); transition: transform .18s ease; }
|
||||
.nav-dropdown-toggle[aria-expanded="true"] .nav-dropdown-icon { transform: translateY(2px) rotate(225deg); }
|
||||
.category-menu { position: absolute; z-index: 30; top: calc(100% - 1px); left: 50%; display: none; grid-template-columns: repeat(2, minmax(170px, 1fr)); width: 430px; padding: 12px; border: 1px solid var(--border-strong); background: var(--bg); transform: translateX(-50%); box-shadow: 0 18px 44px rgba(0,0,0,.38); }
|
||||
.category-menu.is-open { display: grid; }
|
||||
.category-menu a { min-height: 40px; padding: 9px 11px; border-bottom: 1px solid var(--border); color: var(--muted); }
|
||||
.category-menu a:hover { background: var(--surface-strong); color: var(--text); }
|
||||
.main-nav a {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
color: var(--muted);
|
||||
font-size: 16px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.main-nav a:hover, .main-nav a[aria-current="page"] { color: var(--text); }
|
||||
.main-nav a[aria-current="page"]::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: -1px;
|
||||
left: 0;
|
||||
height: 3px;
|
||||
background: var(--olive);
|
||||
}
|
||||
|
||||
.header-actions { display: flex; gap: 8px; }
|
||||
.header-actions > .social-links { margin-right: 5px; padding-right: 10px; border-right: 1px solid var(--border); }
|
||||
.icon-button {
|
||||
display: grid;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
padding: 0;
|
||||
place-items: center;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
color: var(--text);
|
||||
cursor: pointer;
|
||||
}
|
||||
.icon-button:hover { background: var(--surface-strong); color: var(--olive); }
|
||||
.icon-button svg { width: 23px; height: 23px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: square; }
|
||||
.menu-button { display: none; }
|
||||
|
||||
.search-form {
|
||||
width: min(760px, calc(100% - var(--gutter) * 2));
|
||||
margin: 0 auto;
|
||||
padding: 16px 0 20px;
|
||||
}
|
||||
.search-form[hidden] { display: none; }
|
||||
.search-form label { display: block; margin-bottom: 8px; color: var(--muted); font-size: 14px; }
|
||||
.search-form > div { display: grid; grid-template-columns: 1fr auto; }
|
||||
.search-form input {
|
||||
min-width: 0;
|
||||
height: 48px;
|
||||
padding: 0 16px;
|
||||
border: 1px solid var(--border-strong);
|
||||
border-right: 0;
|
||||
border-radius: 0;
|
||||
background: var(--surface);
|
||||
color: var(--text);
|
||||
font-size: 17px;
|
||||
}
|
||||
.search-form button, .read-link, .empty-state a {
|
||||
border: 1px solid var(--olive);
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
color: var(--text);
|
||||
cursor: pointer;
|
||||
}
|
||||
.search-form button { padding: 0 24px; }
|
||||
.search-form button:hover, .read-link:hover, .empty-state a:hover { background: var(--olive); color: var(--bg); }
|
||||
|
||||
.feed-shell, .article-page, .related-section, .site-footer {
|
||||
position: relative;
|
||||
width: min(var(--max), calc(100% - var(--gutter) * 2));
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.page-heading { padding: 56px 0 46px; }
|
||||
.page-heading h1 {
|
||||
max-width: 900px;
|
||||
margin: 0;
|
||||
font-size: 68px;
|
||||
font-weight: 700;
|
||||
line-height: .98;
|
||||
}
|
||||
@media (min-width: 981px) {
|
||||
.home-template .page-heading {
|
||||
position: relative;
|
||||
left: 50%;
|
||||
width: min(1600px, calc(100vw - var(--gutter) * 2));
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
.home-template .page-heading h1 {
|
||||
max-width: none;
|
||||
font-size: clamp(58px, 4vw, 68px);
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
.page-heading > p { margin: 20px 0 0; color: var(--muted); }
|
||||
|
||||
.lead-story {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1.25fr) minmax(340px, .95fr);
|
||||
min-height: 480px;
|
||||
max-height: 680px;
|
||||
border-bottom: 1px solid var(--border-strong);
|
||||
}
|
||||
.lead-media { min-height: 480px; max-height: 680px; overflow: hidden; background: var(--surface); }
|
||||
.lead-media img, .lead-media video { width: 100%; height: 100%; object-fit: cover; transition: transform .45s ease; }
|
||||
.lead-media:hover img { transform: scale(1.015); }
|
||||
.lead-copy { display: flex; flex-direction: column; justify-content: center; padding: 34px 0 36px 44px; }
|
||||
.lead-copy h2 { margin: 24px 0 22px; font-size: 40px; line-height: 1.14; }
|
||||
.lead-copy h2 a:hover { color: var(--text); text-decoration: underline; text-decoration-color: var(--olive); text-underline-offset: 7px; }
|
||||
.lead-copy > p { max-width: 580px; margin: 0; color: var(--muted); font-size: 20px; line-height: 1.5; }
|
||||
.read-link { width: fit-content; margin-top: 30px; padding: 10px 15px; font-size: 15px; }
|
||||
.read-link span { margin-left: 8px; }
|
||||
|
||||
.article-meta { display: flex; align-items: center; flex-wrap: wrap; gap: 0; color: var(--muted); font-size: 14px; }
|
||||
.article-meta > * { display: inline-flex; align-items: center; }
|
||||
.article-meta > * + *::before { content: ""; width: 1px; height: 18px; margin: 0 16px; background: var(--border-strong); }
|
||||
.article-meta .category-link { color: var(--olive); }
|
||||
.article-meta .producer-link { color: var(--red); }
|
||||
|
||||
.feed-list { width: 100%; }
|
||||
.feed-list-top { border-top: 1px solid var(--border-strong); }
|
||||
.feed-row {
|
||||
display: grid;
|
||||
grid-template-columns: 350px minmax(0, 1fr);
|
||||
gap: 34px;
|
||||
padding: 22px 0;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
.feed-row-media { aspect-ratio: 16 / 9; overflow: hidden; background: var(--surface); }
|
||||
.feed-row-media img, .feed-row-media video { width: 100%; height: 100%; object-fit: cover; transition: transform .35s ease; }
|
||||
.feed-row-media:hover img { transform: scale(1.02); }
|
||||
.feed-row-copy { align-self: center; min-width: 0; }
|
||||
.feed-row h2 { margin: 16px 0 8px; font-size: 25px; line-height: 1.2; }
|
||||
.feed-row h2 a:hover { color: var(--text); text-decoration: underline; text-decoration-color: var(--olive); text-underline-offset: 5px; }
|
||||
.feed-row p { max-width: 760px; margin: 0; color: var(--muted); font-size: 17px; line-height: 1.5; }
|
||||
.preview-social { margin-top: 14px; }
|
||||
.media-placeholder { display: grid; width: 100%; height: 100%; place-items: center; background: var(--surface); }
|
||||
.media-placeholder img { width: 76px; height: 76px; opacity: .28; object-fit: contain; }
|
||||
.feed-media { position: relative; }
|
||||
.feed-media-feature, .feed-media-feature > img, .feed-media-feature > .media-placeholder { display: block; width: 100%; height: 100%; }
|
||||
.feed-media-track { display: flex; width: 100%; height: 100%; overflow-x: auto; overflow-y: hidden; scroll-snap-type: x mandatory; scrollbar-width: none; }
|
||||
.feed-media-track::-webkit-scrollbar { display: none; }
|
||||
.feed-media-slide { flex: 0 0 100%; width: 100%; height: 100%; scroll-snap-align: start; }
|
||||
.feed-media-slide > a, .feed-media-slide img, .feed-media-slide video { display: block; width: 100%; height: 100%; }
|
||||
.feed-media-slide img, .feed-media-slide video { object-fit: cover; }
|
||||
.feed-media-count { position: absolute; top: 10px; right: 10px; z-index: 2; padding: 4px 8px; border-radius: 999px; background: rgba(0,0,0,.68); color: #fff; font-size: 12px; line-height: 1; pointer-events: none; }
|
||||
|
||||
.pagination { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; min-height: 90px; font-size: 15px; }
|
||||
.pagination > :last-child { justify-self: end; }
|
||||
.pagination span { color: var(--faint); }
|
||||
.pagination .older-posts { grid-column: 3; justify-self: end; }
|
||||
.pagination .newer-posts { grid-column: 1; }
|
||||
.pagination .page-number { grid-column: 2; grid-row: 1; }
|
||||
|
||||
.home-seo {
|
||||
max-width: 960px;
|
||||
margin: 54px auto 0;
|
||||
padding: 40px 0 0;
|
||||
border-top: 1px solid var(--border-strong);
|
||||
}
|
||||
.home-seo h2 { margin: 0 0 24px; font-size: 34px; line-height: 1.15; }
|
||||
.home-seo p { margin: 0 0 18px; color: var(--muted); font-size: 17px; line-height: 1.7; }
|
||||
.home-seo p:last-child { margin-bottom: 0; }
|
||||
|
||||
.taxonomy-heading { padding-bottom: 34px; }
|
||||
.taxonomy-heading > p { margin: 0 0 10px; color: var(--olive); font-size: 15px; text-transform: uppercase; }
|
||||
.taxonomy-heading h1 { font-size: 56px; }
|
||||
|
||||
.article-page { padding-top: 56px; }
|
||||
.article-header { max-width: 960px; margin: 0 auto 42px; }
|
||||
.article-breadcrumbs { display: flex; gap: 12px; margin-bottom: 28px; color: var(--muted); font-size: 14px; }
|
||||
.article-breadcrumbs span { color: var(--faint); }
|
||||
.article-header h1 { margin: 0; font-size: 58px; line-height: 1.06; }
|
||||
.article-lead { max-width: 850px; margin: 26px 0 0; color: var(--muted); font-size: 23px; line-height: 1.45; }
|
||||
.article-byline { display: flex; gap: 24px; margin-top: 28px; color: var(--muted); font-size: 14px; }
|
||||
.article-byline a { color: var(--red); }
|
||||
.article-media { display: grid; gap: 12px; margin-bottom: 46px; }
|
||||
.article-media figure { margin: 0; background: var(--surface); }
|
||||
.article-media img, .article-media video { width: 100%; max-height: 760px; object-fit: contain; }
|
||||
.article-layout { display: grid; grid-template-columns: minmax(0, 760px) 260px; justify-content: center; gap: 78px; }
|
||||
.article-body { font-size: 21px; line-height: 1.7; }
|
||||
.article-body p { margin: 0 0 26px; }
|
||||
.gh-content > * { max-width: 100%; }
|
||||
.gh-content a { color: var(--olive); text-decoration: underline; text-underline-offset: 3px; }
|
||||
.gh-content figure, .gh-content .kg-card { margin: 32px 0; }
|
||||
.gh-content img, .gh-content video { width: 100%; height: auto; }
|
||||
.gh-content blockquote { margin: 30px 0; padding-left: 24px; border-left: 3px solid var(--olive); color: var(--muted); }
|
||||
.kg-width-wide, .kg-width-full { width: 100%; }
|
||||
.kg-gallery-container { display: flex; flex-direction: column; gap: 10px; }
|
||||
.kg-gallery-row { display: flex; gap: 10px; }
|
||||
.kg-gallery-image { flex: 1 1 0; min-width: 0; margin: 0; overflow: hidden; background: var(--surface); }
|
||||
.kg-gallery-image img { width: 100%; height: 100%; margin: 0; object-fit: cover; cursor: zoom-in; }
|
||||
.media-lightbox { width: 100%; height: 100%; max-width: none; max-height: none; padding: 0; border: 0; background: rgba(0,0,0,.94); }
|
||||
.media-lightbox::backdrop { background: rgba(0,0,0,.94); }
|
||||
.media-lightbox img { width: 100%; height: 100%; object-fit: contain; }
|
||||
.media-lightbox button { position: fixed; top: 18px; right: 18px; z-index: 2; width: 44px; height: 44px; border: 1px solid var(--border-strong); background: var(--bg); color: var(--text); font-size: 28px; cursor: pointer; }
|
||||
.article-facts { align-self: start; border-top: 2px solid var(--olive); }
|
||||
.article-facts > div { padding: 18px 0; border-bottom: 1px solid var(--border); }
|
||||
.article-facts span { display: block; margin-bottom: 4px; color: var(--faint); font-size: 13px; text-transform: uppercase; }
|
||||
.article-facts a { font-size: 17px; }
|
||||
.article-facts .source-link { display: block; margin-top: 22px; color: var(--muted); font-size: 14px; }
|
||||
.social-links { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-top: 13px; }
|
||||
.social-link { display: inline-flex; min-height: 34px; align-items: center; gap: 7px; padding: 5px 10px; border: 1px solid var(--border); color: var(--muted); font-size: 14px; line-height: 1; transition: border-color .18s ease, color .18s ease, background .18s ease; }
|
||||
.social-link:hover { border-color: var(--border-strong); background: var(--surface-strong); color: var(--text); }
|
||||
.social-link svg { width: 18px; height: 18px; fill: currentColor; }
|
||||
.social-link--vk:hover { color: #7ca8e8; }
|
||||
.social-link--tg:hover { color: #58b9e8; }
|
||||
.social-links--compact { gap: 4px; margin-top: 0; }
|
||||
.social-links--compact .social-link { width: 34px; min-height: 34px; justify-content: center; padding: 0; }
|
||||
.social-links--compact .social-link svg { width: 17px; height: 17px; }
|
||||
.about-social { margin-top: 42px; padding-top: 24px; border-top: 1px solid var(--border-strong); }
|
||||
.about-social > span { color: var(--faint); font-size: 13px; text-transform: uppercase; }
|
||||
.related-section { margin-top: 90px; border-top: 1px solid var(--border-strong); }
|
||||
.related-section > h2 { margin: 0; padding: 34px 0 18px; font-size: 32px; }
|
||||
|
||||
.empty-state, .not-found { min-height: 56vh; display: flex; flex-direction: column; justify-content: center; align-items: flex-start; }
|
||||
.empty-state h2, .not-found h1 { margin: 0; font-size: 42px; }
|
||||
.empty-state p { color: var(--muted); }
|
||||
.empty-state a { margin-top: 16px; padding: 10px 15px; }
|
||||
.not-found > p { margin: 0; color: var(--red); font-size: 18px; }
|
||||
.not-found a { margin-top: 24px; color: var(--olive); }
|
||||
|
||||
.site-footer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
margin-top: 84px;
|
||||
padding: 34px 0 46px;
|
||||
border-top: 1px solid var(--border-strong);
|
||||
color: var(--muted);
|
||||
font-size: 14px;
|
||||
}
|
||||
.footer-brand { color: var(--text); font-size: 20px; font-weight: 700; }
|
||||
.site-footer p { margin: 7px 0 0; }
|
||||
.site-footer nav { display: flex; gap: 24px; }
|
||||
.site-footer .social-links { margin-top: 18px; }
|
||||
|
||||
@media (max-width: 980px) {
|
||||
.header-inner { grid-template-columns: 150px 1fr auto; gap: 16px; }
|
||||
.main-nav { gap: 22px; }
|
||||
.main-nav a { font-size: 14px; }
|
||||
.page-heading h1 { font-size: 56px; }
|
||||
.lead-story { grid-template-columns: 1.1fr .9fr; min-height: 420px; }
|
||||
.lead-media { min-height: 420px; }
|
||||
.lead-copy { padding-left: 30px; }
|
||||
.lead-copy h2 { font-size: 33px; }
|
||||
.feed-row { grid-template-columns: 290px minmax(0, 1fr); gap: 26px; }
|
||||
.article-layout { grid-template-columns: minmax(0, 680px) 220px; gap: 44px; }
|
||||
}
|
||||
|
||||
@media (max-width: 760px) {
|
||||
:root { --gutter: 16px; }
|
||||
body { font-size: 17px; }
|
||||
.home-seo { margin-top: 38px; padding-top: 30px; }
|
||||
.home-seo h2 { font-size: 28px; }
|
||||
.home-seo p { font-size: 16px; line-height: 1.65; }
|
||||
.header-inner { min-height: 64px; grid-template-columns: 1fr auto; }
|
||||
.brand img { width: 38px; height: 38px; }
|
||||
.main-nav {
|
||||
position: absolute;
|
||||
top: 64px;
|
||||
right: 0;
|
||||
left: 0;
|
||||
display: none;
|
||||
padding: 12px var(--gutter) 18px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
background: var(--bg);
|
||||
}
|
||||
.main-nav.is-open { display: grid; }
|
||||
.main-nav a { min-height: 44px; border-bottom: 1px solid var(--border); font-size: 16px; }
|
||||
.nav-dropdown { display: block; }
|
||||
.nav-dropdown-toggle { width: 100%; min-height: 44px; border-bottom: 1px solid var(--border); text-align: left; font-size: 16px; }
|
||||
.category-menu { position: static; width: 100%; grid-template-columns: 1fr; padding: 0 0 8px 14px; border: 0; box-shadow: none; transform: none; }
|
||||
.category-menu a { font-size: 15px; }
|
||||
.main-nav a[aria-current="page"]::after { display: none; }
|
||||
.menu-button { display: grid; }
|
||||
.page-heading { padding: 38px 0 30px; }
|
||||
.page-heading h1, .taxonomy-heading h1 { font-size: 44px; line-height: 1; }
|
||||
.lead-story { display: block; min-height: 0; max-height: none; }
|
||||
.lead-media { min-height: 0; max-height: min(72vh, 560px); aspect-ratio: 4 / 3; }
|
||||
.lead-copy { padding: 25px 0 34px; }
|
||||
.lead-copy h2 { margin: 20px 0 15px; font-size: 32px; }
|
||||
.lead-copy > p { font-size: 18px; }
|
||||
.feed-row { display: block; padding: 24px 0; }
|
||||
.feed-row-media { width: 100%; max-height: min(72vh, 560px); aspect-ratio: 4 / 3; }
|
||||
.feed-row-copy { padding-top: 16px; }
|
||||
.feed-row h2 { margin: 10px 0 8px; font-size: 24px; }
|
||||
.feed-row p { display: block; font-size: 16px; }
|
||||
.preview-social { margin-top: 10px; }
|
||||
.preview-social .social-link { width: 30px; min-height: 30px; }
|
||||
.article-meta { font-size: 12px; }
|
||||
.article-meta time { display: none; }
|
||||
.article-meta > * + *::before { height: 14px; margin: 0 10px; }
|
||||
.article-meta .category-link::before { display: none; }
|
||||
.article-header { margin-bottom: 30px; }
|
||||
.article-header h1 { font-size: 42px; }
|
||||
.article-lead { font-size: 20px; }
|
||||
.article-layout { display: block; }
|
||||
.article-body { font-size: 19px; }
|
||||
.article-facts { margin-top: 42px; }
|
||||
.related-section { margin-top: 64px; }
|
||||
}
|
||||
|
||||
@media (max-width: 460px) {
|
||||
.feed-row h2 { font-size: 22px; line-height: 1.2; }
|
||||
.article-meta .producer-link::before { display: none; }
|
||||
.article-meta .category-link { display: none; }
|
||||
.article-header h1 { font-size: 36px; }
|
||||
.article-byline { display: grid; gap: 7px; }
|
||||
.site-footer { display: grid; gap: 24px; }
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
html { scroll-behavior: auto; }
|
||||
*, *::before, *::after { transition-duration: .01ms !important; }
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 46 KiB |
@@ -0,0 +1,86 @@
|
||||
(() => {
|
||||
document.querySelectorAll('[data-feed-media]').forEach((container) => {
|
||||
const source = container.querySelector('.feed-media-source');
|
||||
const feature = container.querySelector('.feed-media-feature');
|
||||
if (!source || !feature) return;
|
||||
|
||||
const videos = [...source.querySelectorAll('video')].map((item) => {
|
||||
const video = item.cloneNode(true);
|
||||
video.removeAttribute('poster');
|
||||
video.controls = true;
|
||||
video.playsInline = true;
|
||||
video.preload = 'metadata';
|
||||
return video;
|
||||
});
|
||||
const images = [...source.querySelectorAll('.kg-gallery-card img, .kg-image-card img')].map((item) => {
|
||||
const link = document.createElement('a');
|
||||
link.href = item.currentSrc || item.src;
|
||||
link.setAttribute('aria-label', item.alt ? `Открыть: ${item.alt}` : 'Открыть изображение');
|
||||
link.appendChild(item.cloneNode(true));
|
||||
return link;
|
||||
});
|
||||
|
||||
const items = videos.length ? [...videos, ...images] : [feature, ...images];
|
||||
if (items.length === 1 && !videos.length) return;
|
||||
const track = document.createElement('div');
|
||||
track.className = 'feed-media-track';
|
||||
items.forEach((item) => {
|
||||
const slide = document.createElement('div');
|
||||
slide.className = 'feed-media-slide';
|
||||
slide.appendChild(item);
|
||||
track.appendChild(slide);
|
||||
});
|
||||
container.replaceChildren(track, source);
|
||||
if (items.length > 1) {
|
||||
const count = document.createElement('span');
|
||||
count.className = 'feed-media-count';
|
||||
count.textContent = `1 / ${items.length}`;
|
||||
container.appendChild(count);
|
||||
track.addEventListener('scroll', () => {
|
||||
const index = Math.round(track.scrollLeft / Math.max(track.clientWidth, 1));
|
||||
count.textContent = `${Math.min(index + 1, items.length)} / ${items.length}`;
|
||||
}, { passive: true });
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
(() => {
|
||||
const button = document.querySelector('[data-menu-toggle]');
|
||||
const nav = document.querySelector('#main-nav');
|
||||
if (!button || !nav) return;
|
||||
button.addEventListener('click', () => {
|
||||
const open = nav.classList.toggle('is-open');
|
||||
button.setAttribute('aria-expanded', String(open));
|
||||
});
|
||||
})();
|
||||
|
||||
(() => {
|
||||
const toggle = document.querySelector('[data-category-toggle]');
|
||||
const menu = document.querySelector('[data-category-menu]');
|
||||
if (!toggle || !menu) return;
|
||||
const close = () => { menu.classList.remove('is-open'); toggle.setAttribute('aria-expanded', 'false'); };
|
||||
toggle.addEventListener('click', (event) => {
|
||||
event.stopPropagation();
|
||||
const open = menu.classList.toggle('is-open');
|
||||
toggle.setAttribute('aria-expanded', String(open));
|
||||
});
|
||||
document.addEventListener('click', (event) => { if (!menu.contains(event.target)) close(); });
|
||||
document.addEventListener('keydown', (event) => { if (event.key === 'Escape') close(); });
|
||||
})();
|
||||
|
||||
(() => {
|
||||
const images = document.querySelectorAll('.gh-content .kg-gallery-image img');
|
||||
if (!images.length || !('HTMLDialogElement' in window)) return;
|
||||
const dialog = document.createElement('dialog');
|
||||
dialog.className = 'media-lightbox';
|
||||
dialog.innerHTML = '<button type="button" aria-label="Закрыть">×</button><img alt="">';
|
||||
const preview = dialog.querySelector('img');
|
||||
dialog.querySelector('button').addEventListener('click', () => dialog.close());
|
||||
dialog.addEventListener('click', (event) => { if (event.target === dialog) dialog.close(); });
|
||||
document.body.appendChild(dialog);
|
||||
images.forEach((image) => image.addEventListener('click', () => {
|
||||
preview.src = image.currentSrc || image.src;
|
||||
preview.alt = image.alt || '';
|
||||
dialog.showModal();
|
||||
}));
|
||||
})();
|
||||
@@ -0,0 +1,81 @@
|
||||
<!doctype html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<!-- Google Tag Manager -->
|
||||
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
|
||||
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
|
||||
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
|
||||
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
|
||||
})(window,document,'script','dataLayer','GTM-MM4FR8LJ');</script>
|
||||
<!-- End Google Tag Manager -->
|
||||
{{#is "home"}}
|
||||
<title>Forma N8 — все новости снаряжения в одном месте</title>
|
||||
{{else}}
|
||||
{{#is "post"}}
|
||||
{{#post}}<title>Forma N8 — {{title}}</title>{{/post}}
|
||||
{{else}}
|
||||
{{#is "tag"}}
|
||||
{{#tag}}<title>Forma N8 — {{name}}</title>{{/tag}}
|
||||
{{else}}
|
||||
<title>Forma N8 — {{meta_title}}</title>
|
||||
{{/is}}
|
||||
{{/is}}
|
||||
{{/is}}
|
||||
<link rel="icon" type="image/png" href="{{asset "images/favi.png"}}">
|
||||
<link rel="stylesheet" href="{{asset "css/screen.css"}}">
|
||||
{{ghost_head}}
|
||||
</head>
|
||||
<body class="{{body_class}}">
|
||||
<!-- Google Tag Manager (noscript) -->
|
||||
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-MM4FR8LJ"
|
||||
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
|
||||
<!-- End Google Tag Manager (noscript) -->
|
||||
<a class="skip-link" href="#content">К содержанию</a>
|
||||
<header class="site-header">
|
||||
<div class="header-inner">
|
||||
<a class="brand" href="{{@site.url}}" aria-label="Forma N8, главная">
|
||||
<img src="{{asset "images/favi.png"}}" width="42" height="42" alt="">
|
||||
<span>FORMA<br>N8</span>
|
||||
</a>
|
||||
<nav class="main-nav" id="main-nav" aria-label="Основная навигация">
|
||||
<a href="{{@site.url}}">Лента</a>
|
||||
<div class="nav-dropdown">
|
||||
<button type="button" class="nav-dropdown-toggle" data-category-toggle aria-expanded="false">Категории <span class="nav-dropdown-icon" aria-hidden="true"></span></button>
|
||||
<div class="category-menu" data-category-menu>
|
||||
{{#get "tags" filter="visibility:public" limit="100" order="name asc"}}
|
||||
{{#foreach tags}}<a href="{{url}}">{{name}}</a>{{/foreach}}
|
||||
{{/get}}
|
||||
</div>
|
||||
</div>
|
||||
<a href="{{@site.url}}/about/">О проекте</a>
|
||||
</nav>
|
||||
<div class="header-actions">
|
||||
{{> "social-links" compact=true}}
|
||||
<button class="icon-button" type="button" data-ghost-search aria-label="Открыть поиск" title="Поиск">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><circle cx="11" cy="11" r="6.5"></circle><path d="m16 16 4 4"></path></svg>
|
||||
</button>
|
||||
<button class="icon-button menu-button" type="button" data-menu-toggle aria-expanded="false" aria-controls="main-nav" aria-label="Открыть меню" title="Меню">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M4 7h16M4 12h16M4 17h16"></path></svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<main id="content">{{{body}}}</main>
|
||||
<footer class="site-footer">
|
||||
<div><a class="footer-brand" href="{{@site.url}}">FORMA N8</a><p>Новости снаряжения и экипировки.</p>{{> "social-links"}}</div>
|
||||
<nav aria-label="Служебная навигация"><a href="{{@site.url}}/rss/">RSS</a><a href="{{@site.url}}/sitemap.xml">Карта сайта</a></nav>
|
||||
</footer>
|
||||
<script src="{{asset "js/site.js"}}" defer></script>
|
||||
<script>
|
||||
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
|
||||
m[i].l=1*new Date();for(var j=0;j<document.scripts.length;j++){if(document.scripts[j].src===r){return;}}
|
||||
k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
|
||||
(window,document,"script","https://mc.yandex.ru/metrika/tag.js","ym");
|
||||
ym(110060335,"init",{clickmap:true,trackLinks:true,accurateTrackBounce:true,webvisor:true});
|
||||
</script>
|
||||
<noscript><div><img src="https://mc.yandex.ru/watch/110060335" style="position:absolute;left:-9999px" alt=""></div></noscript>
|
||||
{{ghost_foot}}
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,2 @@
|
||||
{{!< default}}
|
||||
<section class="feed-shell not-found"><p>{{statusCode}}</p><h1>{{message}}</h1><a href="{{@site.url}}">Вернуться в ленту</a></section>
|
||||
@@ -0,0 +1,38 @@
|
||||
{{!< default}}
|
||||
<section class="feed-shell">
|
||||
<header class="page-heading"><h1>Новости тактического снаряжения и экипировки</h1></header>
|
||||
{{#foreach posts}}
|
||||
{{#if @first}}
|
||||
{{#is "home"}}
|
||||
<article class="lead-story">
|
||||
<div class="lead-media feed-media" data-feed-media>
|
||||
<a class="feed-media-feature" href="{{url}}">{{#if feature_image}}<img src="{{img_url feature_image size="xl"}}" alt="{{#if feature_image_alt}}{{feature_image_alt}}{{else}}{{title}}{{/if}}">{{else}}<span class="media-placeholder"><img src="{{asset "images/favi.png"}}" alt=""></span>{{/if}}</a>
|
||||
<div class="feed-media-source" hidden>{{content}}</div>
|
||||
</div>
|
||||
<div class="lead-copy">
|
||||
<div class="article-meta">{{#if primary_tag}}<a class="category-link" href="{{primary_tag.url}}">{{primary_tag.name}}</a>{{/if}}<time datetime="{{date format="YYYY-MM-DD"}}">{{date format="DD.MM.YYYY"}}</time></div>
|
||||
<h2><a href="{{url}}">{{title}}</a></h2>
|
||||
<p>{{excerpt words="42"}}</p>
|
||||
<a class="read-link" href="{{url}}">Читать новость <span aria-hidden="true">→</span></a>
|
||||
<div class="preview-social">{{> "social-links" compact=true}}</div>
|
||||
</div>
|
||||
</article>
|
||||
{{else}}
|
||||
{{> "post-row"}}
|
||||
{{/is}}
|
||||
{{else}}
|
||||
{{> "post-row"}}
|
||||
{{/if}}
|
||||
{{else}}
|
||||
<div class="empty-state"><h2>Публикаций пока нет</h2><p>Лента скоро наполнится новостями.</p></div>
|
||||
{{/foreach}}
|
||||
{{> "pagination-ru"}}
|
||||
{{#is "home"}}
|
||||
<section class="home-seo" aria-labelledby="home-seo-title">
|
||||
<h2 id="home-seo-title">О новостной ленте Forma N8</h2>
|
||||
<p>Forma N8 — лента новостей о тактическом снаряжении, экипировке и EDC. Мы собираем новинки с десятков источников и публикуем в одном месте: плитоносцы и бронезащита, подсумки и разгрузочные системы, боевые брюки и рубашки, прицелы и оптика, тактические фонари, средства связи, медицина и ночные приборы.</p>
|
||||
<p>В ленте — новинки российских и зарубежных производителей: Ars Arma, Wartech, SSO, Stich Profi, Giena Tactical, 5.45 Design, Red Cliff, VOIN, Sturmer, БАРС, SRVV, ANA Tactical, Mordor Tac, Centurion Gear, ENOTACTICAL, Black Buckle, MILGEAR, SKIF Armor, Atlant Armour, БронеЁж, R5 GEAR, VINDEX, JAEGER Equipment, Margul Gear, Gordeev Tactical, IGLA TAC, STRIX TAC, Колчуга, APEX, Пересвет, Гарсинг и многих других. Отслеживаем оптику Диполь, ARTELV и ARKON, гарнитуры VULCAN, Fidem и ОКБ Октава, фонари Nicron, патчи BAD GRINGO и RedWar Patch, ножи DAGGERR, Morpheus Knives и N.C.Custom.</p>
|
||||
<p>Темы ленты охватывают весь комплект тактической экипировки: системы MOLLE и Molle-Minus, плиты стандартов Гранит, SAPI и ESAPI, ткани Cordura и NYCO, расцветки Multicam, Tiger Stripe и EMR. Новинки магазинов Академия Снаряжения, Semper Fi, ФИНИСТ и Империя ножей, обновления линеек, цены и отзывы пользователей — всё в одной новостной ленте о снаряжении.</p>
|
||||
</section>
|
||||
{{/is}}
|
||||
</section>
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "forma-n8",
|
||||
"description": "Strict editorial theme for Forma N8",
|
||||
"version": "1.0.0",
|
||||
"author": {
|
||||
"name": "Forma N8",
|
||||
"email": "admin@f-n8.ru"
|
||||
},
|
||||
"keywords": ["ghost-theme", "forma-n8", "news"],
|
||||
"engines": {
|
||||
"ghost": ">=6.0.0"
|
||||
},
|
||||
"license": "UNLICENSED",
|
||||
"config": {
|
||||
"posts_per_page": 25,
|
||||
"card_assets": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
{{!< default}}
|
||||
{{#post}}<article class="article-page">{{#if @page.show_title_and_feature_image}}<header class="article-header"><h1>{{title}}</h1>{{#if custom_excerpt}}<p class="article-lead">{{custom_excerpt}}</p>{{/if}}</header>{{#if feature_image}}<figure class="article-media"><img src="{{img_url feature_image size="xl"}}" alt="{{title}}"></figure>{{/if}}{{/if}}<div class="article-layout"><div class="article-body gh-content">{{content}}<aside class="about-social"><span>Forma N8 в социальных сетях</span>{{> "social-links"}}</aside></div></div></article>{{/post}}
|
||||
@@ -0,0 +1,9 @@
|
||||
{{#if pagination.pages}}
|
||||
{{#match pagination.pages ">" 1}}
|
||||
<nav class="pagination" role="navigation" aria-label="Пагинация">
|
||||
{{#if pagination.prev}}<a class="newer-posts" href="{{page_url pagination.prev}}">← Новые публикации</a>{{/if}}
|
||||
<span class="page-number">Страница {{pagination.page}} из {{pagination.pages}}</span>
|
||||
{{#if pagination.next}}<a class="older-posts" href="{{page_url pagination.next}}">Старые публикации →</a>{{/if}}
|
||||
</nav>
|
||||
{{/match}}
|
||||
{{/if}}
|
||||
@@ -0,0 +1,12 @@
|
||||
<article class="feed-row">
|
||||
<div class="feed-row-media feed-media" data-feed-media>
|
||||
<a class="feed-media-feature" href="{{url}}">{{#if feature_image}}<img src="{{img_url feature_image size="m"}}" alt="{{#if feature_image_alt}}{{feature_image_alt}}{{else}}{{title}}{{/if}}" loading="lazy">{{else}}<span class="media-placeholder"><img src="{{asset "images/favi.png"}}" alt=""></span>{{/if}}</a>
|
||||
<div class="feed-media-source" hidden>{{content}}</div>
|
||||
</div>
|
||||
<div class="feed-row-copy">
|
||||
<div class="article-meta">{{#if primary_tag}}<a class="category-link" href="{{primary_tag.url}}">{{primary_tag.name}}</a>{{/if}}<time datetime="{{date format="YYYY-MM-DD"}}">{{date format="DD.MM.YYYY"}}</time></div>
|
||||
<h2><a href="{{url}}">{{title}}</a></h2>
|
||||
<p>{{excerpt words="28"}}</p>
|
||||
<div class="preview-social">{{> "social-links" compact=true}}</div>
|
||||
</div>
|
||||
</article>
|
||||
@@ -0,0 +1,10 @@
|
||||
<div class="social-links{{#if compact}} social-links--compact{{/if}}" aria-label="Forma N8 в социальных сетях">
|
||||
<a class="social-link social-link--vk" href="https://vk.com/forma_n8" target="_blank" rel="noopener noreferrer" aria-label="Forma N8 во ВКонтакте" title="ВКонтакте">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12.8 17.6C5.4 17.6 1.2 12.5 1 4h3.7c.1 6.2 2.9 8.8 5.1 9.3V4h3.5v5.3c2.2-.2 4.5-2.6 5.3-5.3H22c-.6 3.3-3.1 5.7-4.9 6.7 1.8.8 4.7 2.9 5.8 6.9h-3.8c-.9-2.6-3.2-4.6-5.8-4.9v4.9h-.5Z"/></svg>
|
||||
{{#unless compact}}<span>ВКонтакте</span>{{/unless}}
|
||||
</a>
|
||||
<a class="social-link social-link--tg" href="https://t.me/forma_n8" target="_blank" rel="noopener noreferrer" aria-label="Forma N8 в Telegram" title="Telegram">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M21.7 3.4 18.5 20.5c-.2 1.2-.9 1.5-1.9.9l-4.9-3.6-2.4 2.3c-.3.3-.5.5-1 .5l.3-5 9.1-8.2c.4-.4-.1-.6-.6-.2L5.9 14.3 1.1 12.8c-1-.3-1-1 .2-1.5L20 2.6c.9-.3 1.8.2 1.7.8Z"/></svg>
|
||||
{{#unless compact}}<span>Telegram</span>{{/unless}}
|
||||
</a>
|
||||
</div>
|
||||
@@ -0,0 +1,20 @@
|
||||
{{!< default}}
|
||||
{{#post}}
|
||||
<article class="article-page">
|
||||
<header class="article-header">
|
||||
<div class="article-breadcrumbs"><a href="{{@site.url}}">Лента</a>{{#if primary_tag}}<span>/</span><a href="{{primary_tag.url}}">{{primary_tag.name}}</a>{{/if}}</div>
|
||||
<h1>{{title}}</h1>
|
||||
{{#if custom_excerpt}}<p class="article-lead">{{custom_excerpt}}</p>{{/if}}
|
||||
<div class="article-byline"><time datetime="{{date format="YYYY-MM-DDTHH:mm:ssZ"}}">{{date format="DD.MM.YYYY · HH:mm"}} ЕКБ</time></div>
|
||||
</header>
|
||||
{{#if feature_image}}<figure class="article-media"><img src="{{img_url feature_image size="xl"}}" alt="{{#if feature_image_alt}}{{feature_image_alt}}{{else}}{{title}}{{/if}}"></figure>{{/if}}
|
||||
<div class="article-layout">
|
||||
<div class="article-body gh-content">{{content}}</div>
|
||||
<aside class="article-facts">
|
||||
{{#if primary_tag}}<div><span>Категория</span><a href="{{primary_tag.url}}">{{primary_tag.name}}</a></div>{{/if}}
|
||||
<div><span>Опубликовано</span><time datetime="{{date format="YYYY-MM-DD"}}">{{date format="DD.MM.YYYY"}}</time></div>
|
||||
<div><span>Наши каналы</span>{{> "social-links"}}</div>
|
||||
</aside>
|
||||
</div>
|
||||
</article>
|
||||
{{/post}}
|
||||
@@ -0,0 +1,6 @@
|
||||
{{!< default}}
|
||||
<section class="feed-shell">
|
||||
{{#tag}}<header class="page-heading taxonomy-heading"><p>Тема</p><h1>{{name}}</h1>{{#if description}}<p>{{description}}</p>{{/if}}</header>{{/tag}}
|
||||
<div class="feed-list">{{#foreach posts}}{{> "post-row"}}{{/foreach}}</div>
|
||||
{{> "pagination-ru"}}
|
||||
</section>
|
||||
Reference in New Issue
Block a user