/* css/fonts.css */
/* Every typeface the «Оформлення» tab offers, served from the site itself
   (public/fonts/, each with its licence beside it — docs/dev/licensing.md).
   A face that no rule uses is never downloaded, so declaring all of them here
   costs nothing and keeps this file the same for every school. The choice
   itself is made by --font-body and --font-heading, which GET /theme.css
   writes. The first stylesheet of /site.css. */

/* Commissioner in two files of one face: the full file only for what lies
   beyond the core (Latin Extended-A, the rest of Cyrillic, €, ≠ ≤ ≥), the
   core — declared last, so checked first — for everything a Ukrainian page
   draws; such a page loads the core alone. */
@font-face {
  font-family: 'Commissioner';
  src: url('/fonts/Commissioner-Variable.woff2') format('woff2');
  font-weight: 400 800;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-0130, U+0132-017F, U+0460-048F, U+0492-04FF, U+20AC, U+2260, U+2264-2265;
}

@font-face {
  font-family: 'Commissioner';
  src: url('/fonts/Commissioner-Core.woff2') format('woff2');
  font-weight: 400 800;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+02BC, U+02C6-02DD, U+0300-030C, U+0400-045F, U+0490-0491,
    U+2007-200B, U+2010-2022, U+2026, U+2030, U+2032-2033, U+2039-203A, U+2044, U+20B4, U+2116,
    U+2122, U+2212;
}

@font-face {
  font-family: 'Fixel Text';
  src: url('/fonts/FixelText-Variable.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Fixel Display';
  src: url('/fonts/FixelDisplay-Variable.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* Fixel in two static styles under names of its own (the «fixel-lite» face):
   the text's bold is the display cut's Bold, the file the headings preload. */
@font-face {
  font-family: 'Fixel Text Lite';
  src: url('/fonts/FixelText-Regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Fixel Text Lite';
  src: url('/fonts/FixelDisplay-Bold.woff2') format('woff2');
  font-weight: 600 800;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Fixel Display Lite';
  src: url('/fonts/FixelDisplay-Bold.woff2') format('woff2');
  font-weight: 600 800;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'e-Ukraine';
  src: url('/fonts/e-Ukraine-Regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'e-Ukraine';
  src: url('/fonts/e-Ukraine-Medium.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'e-Ukraine';
  src: url('/fonts/e-Ukraine-Bold.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Playfair';
  src: url('/fonts/Playfair-Variable.woff2') format('woff2');
  font-weight: 300 900;
  font-style: normal;
  font-display: swap;
}

/* Noto Sans Condensed: sign lettering and headings — the upstream Noto Sans
   instanced at its condensed width, one file a weight, under a family name of
   its own. */
@font-face {
  font-family: 'Noto Sans Condensed';
  src: url('/fonts/NotoSansCondensed-Medium.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Piazzolla';
  src: url('/fonts/Piazzolla-Black.woff2') format('woff2');
  font-weight: 900;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Noto Sans Condensed';
  src: url('/fonts/NotoSansCondensed-ExtraBold.woff2') format('woff2');
  font-weight: 800;
  font-style: normal;
  font-display: swap;
}

/* Until the condensed face arrives: the device's own narrow sans, scaled to
   its widths and line metrics, so a late swap moves no line. */
@font-face {
  font-family: 'Noto Sans Condensed Fallback';
  src: local('Arial Narrow Bold'), local('ArialNarrow-Bold'), local('Liberation Sans Narrow Bold'),
    local('LiberationSansNarrow-Bold');
  font-weight: 500 800;
  font-style: normal;
  size-adjust: 107.6%;
  ascent-override: 99.4%;
  descent-override: 27.2%;
  line-gap-override: 0%;
}

/* The same for the text face: Arial scaled to Fixel Text's widths and line
   metrics. */
@font-face {
  font-family: 'Fixel Text Lite Fallback';
  src: local('Arial'), local('ArialMT'), local('Liberation Sans'), local('LiberationSans');
  font-weight: 400;
  font-style: normal;
  size-adjust: 101.9%;
  ascent-override: 88.4%;
  descent-override: 18.7%;
  line-gap-override: 28.5%;
}

/* Wix Madefor: static cuts, each declared over the weight range it stands
   for, so a 600 or 700 heading uses the ExtraBold file as it is. */
@font-face {
  font-family: 'Wix Madefor Display';
  src: url('/fonts/WixMadeforDisplay-ExtraBold.woff2') format('woff2');
  font-weight: 600 900;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Wix Madefor Text';
  src: url('/fonts/WixMadeforText-Regular.woff2') format('woff2');
  font-weight: 300 500;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Wix Madefor Text';
  src: url('/fonts/WixMadeforText-Bold.woff2') format('woff2');
  font-weight: 600 900;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Piazzolla';
  src: url('/fonts/Piazzolla-BlackItalic.woff2') format('woff2');
  font-weight: 900;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: 'Arsenal';
  src: url('/fonts/Arsenal-Regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Arsenal';
  src: url('/fonts/Arsenal-Bold.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* Vollkorn: static cuts, one file a style («Стенд»'s headings). */
@font-face {
  font-family: 'Vollkorn';
  src: url('/fonts/Vollkorn-Regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Vollkorn';
  src: url('/fonts/Vollkorn-Bold.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* Noto Serif: static cuts of the upstream variable Noto Serif at the normal
   width — Regular, Italic and Bold. */
@font-face {
  font-family: 'Noto Serif';
  src: url('/fonts/NotoSerif-Regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Noto Serif';
  src: url('/fonts/NotoSerif-Italic.woff2') format('woff2');
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: 'Noto Serif';
  src: url('/fonts/NotoSerif-Bold.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* Spectral: static cuts — Regular, Italic and SemiBold. Its own U+02BC reads
   as a prime at large sizes and its «№» (U+2116) is narrow and dark beside
   its digits, so the range leaves those two characters out and they come
   from the next face of the stack (Commissioner). */
@font-face {
  font-family: 'Spectral';
  src: url('/fonts/Spectral-Regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-02BB, U+02BD-2115, U+2117-FFFF;
}

@font-face {
  font-family: 'Spectral';
  src: url('/fonts/Spectral-Italic.woff2') format('woff2');
  font-weight: 400;
  font-style: italic;
  font-display: swap;
  unicode-range: U+0000-02BB, U+02BD-2115, U+2117-FFFF;
}

@font-face {
  font-family: 'Spectral';
  src: url('/fonts/Spectral-SemiBold.woff2') format('woff2');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-02BB, U+02BD-2115, U+2117-FFFF;
}

/* Playfair Print: two static cuts of Playfair 2 (ExtraBold and Italic) under
   their own family name, so they never mix with the variable Playfair above. */
@font-face {
  font-family: 'Playfair Print';
  src: url('/fonts/Playfair-ExtraBold.woff2') format('woff2');
  font-weight: 800;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Playfair Print';
  src: url('/fonts/Playfair-Italic.woff2') format('woff2');
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

/* Noto Sans: static cuts for text, one file a style. «Газета» sets its
   italics in Playfair Print; «Стенд» uses the Italic below. */
@font-face {
  font-family: 'Noto Sans';
  src: url('/fonts/NotoSans-Regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Noto Sans';
  src: url('/fonts/NotoSans-Italic.woff2') format('woff2');
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: 'Noto Sans';
  src: url('/fonts/NotoSans-Bold.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* css/base.css */
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  -webkit-text-size-adjust: 100%;
}

body {
  font-family: var(--font-body);
  color: var(--body);
  background: var(--paper);
  font-size: var(--fs-text);
  line-height: var(--lh-text);
}

/* Tabular figures only where numbers stand in columns — a table, the
   numbers block of the home page — not in running text, where some faces
   draw a slashed or odd-looking zero in that set. */
table,
.home-numbers-list,
[class*='-figures'],
.vitryna-stats {
  font-variant-numeric: tabular-nums;
}

img,
picture,
svg {
  max-width: 100%;
  display: block;
}

/* Images from the files table carry width/height attributes (issue #208), so
   the page does not jump while they load. An attribute height is a CSS
   height, though: without this rule a photo capped by max-width would keep
   its full height and stretch. Every rule that sizes an image on purpose
   (object-fit boxes, the hero) is a class selector and still wins. */
img {
  height: auto;
}

/* A photo's focal point (growth story 74): the `img` filter prints data-fx / data-fy (0..10, in tenths) for a
   file that has one, these rules turn them into custom properties, and every object-position on the site
   reads them (test/infra/cssFocus.test.js). No script, no style attribute. */
img[data-fx="0"] { --fx: 0% }
img[data-fx="1"] { --fx: 10% }
img[data-fx="2"] { --fx: 20% }
img[data-fx="3"] { --fx: 30% }
img[data-fx="4"] { --fx: 40% }
img[data-fx="5"] { --fx: 50% }
img[data-fx="6"] { --fx: 60% }
img[data-fx="7"] { --fx: 70% }
img[data-fx="8"] { --fx: 80% }
img[data-fx="9"] { --fx: 90% }
img[data-fx="10"] { --fx: 100% }
img[data-fy="0"] { --fy: 0% }
img[data-fy="1"] { --fy: 10% }
img[data-fy="2"] { --fy: 20% }
img[data-fy="3"] { --fy: 30% }
img[data-fy="4"] { --fy: 40% }
img[data-fy="5"] { --fy: 50% }
img[data-fy="6"] { --fy: 60% }
img[data-fy="7"] { --fy: 70% }
img[data-fy="8"] { --fy: 80% }
img[data-fy="9"] { --fy: 90% }
img[data-fy="10"] { --fy: 100% }
img[data-fx] {
  object-position: var(--fx, 50%) var(--fy, 50%);
}

a {
  color: var(--blue);
  text-decoration: none;
}

/* A link inside a sentence is told apart from the words around it by more
   than its colour (WCAG 1.4.1, axe link-in-text-block): the text of a page
   or a post, a contact line, a search result's section. Links that carry a
   class of their own — cards, menus, buttons — are styled by it. */
p a:not([class]) {
  text-decoration: underline;
  text-underline-offset: 0.15em;
}


input,
select,
textarea,
.photo-slot,
[class*='card'] {
  border-radius: var(--radius);
  box-shadow: none;
}

button,
[class*='btn'] {
  border-radius: var(--radius-button);
  box-shadow: none;
}

/* Headings take the heading face (--font-heading, «Оформлення»); everything
   else keeps the text face set on body. */
h1,
h2,
h3,
h4,
.page-h1,
.hero-title,
.logo-wordmark,
.footer-org-name,
.news-card-title,
.album-card-title {
  font-family: var(--font-heading);
}

.container {
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--space-8); 
}

@media (max-width: 1279px) {
  .container {
    padding-inline: 32px;
  }
}

@media (max-width: 767px) {
  .container {
    padding-inline: var(--space-5); 
  }
}



.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: var(--space-3);
  z-index: 1000;
  background: var(--paper);
  color: var(--blue);
  padding: var(--space-3) var(--space-5);
  font-weight: 700;
  border: 1.5px solid var(--blue);
}

.skip-link:focus {
  left: var(--space-5);
}

/* A hosted site still on review: a strip over every public page. */
.review-banner {
  background: var(--chrome-tint);
  border-bottom: 1px solid var(--chrome-tint-line);
  color: var(--ink);
  padding: var(--space-2) var(--space-4);
  font-size: 0.9rem;
  text-align: center;
}

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}


.md-align-left {
  text-align: left;
}

.md-align-center {
  text-align: center;
}

.md-align-right {
  text-align: right;
}

.md-indent {
  padding-left: var(--space-7);
}


figure {
  width: fit-content;
  max-width: 100%;
  margin: var(--space-5) auto;
}

figure.md-align-left,
.md-align-left figure {
  margin-left: 0;
  margin-right: auto;
}

figure.md-align-center,
.md-align-center figure {
  margin-inline: auto;
}

figure.md-align-right,
.md-align-right figure {
  margin-left: auto;
  margin-right: 0;
}

figure img {
  max-width: 100%;
  border-radius: 2px;
}

figcaption {
  margin-top: var(--space-2);
  color: var(--muted);
  font-size: var(--fs-meta-lg);
  text-align: center;
}

blockquote {
  margin: var(--space-5) 0;
  padding-left: var(--space-5);
  border-left: 3px solid var(--accent);
  color: var(--body);
  font-style: italic;
}

/* Content blocks emitted by src/lib/renderMarkdown.js */

.md-table {
  overflow-x: auto;
  margin: var(--space-5) 0;
}

.md-table table {
  border-collapse: collapse;
  min-width: 100%;
  font-size: var(--fs-text);
}

.md-table th,
.md-table td {
  border: 1px solid var(--line);
  padding: var(--space-2) var(--space-4);
  text-align: left;
  vertical-align: top;
}

.md-table th {
  background: var(--line-soft);
  font-weight: 700;
}

/* Low vision turns --line-soft yellow, which is 1.3:1 against the white header
   text: the header row takes the page colours and a heavy rule instead. */
:root[data-theme='low-vision'] .md-table th {
  background: var(--paper);
  color: var(--ink);
  border-bottom: 3px solid var(--line);
}

/* A table that scrolls sideways is a focusable region (scroll-tables.js);
   the outline is drawn inside the frame so no ancestor can clip it. */
.md-table:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.md-map,
.md-video {
  width: 100%;
  margin: var(--space-6) 0;
}

.md-map iframe,
.md-video iframe {
  display: block;
  width: 100%;
  border: 1px solid var(--line);
}

.md-map iframe {
  height: 360px;
}

.md-video iframe {
  aspect-ratio: 16 / 9;
  height: auto;
  border: 0;
}

.md-map figcaption a {
  font-weight: 600;
}

.md-file {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  margin: var(--space-4) 0;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--line);
  color: var(--ink);
}

.md-file:hover {
  border-color: var(--accent);
}

.md-file-title {
  flex: 1;
  font-weight: 600;
}

.md-file-meta {
  color: var(--muted);
  font-size: var(--fs-meta-lg);
  white-space: nowrap;
}

.md-file-action {
  color: var(--accent);
  font-weight: 600;
  white-space: nowrap;
}

.md-callout {
  margin: var(--space-5) 0;
  padding: var(--space-4) var(--space-5);
  border-left: 4px solid var(--blue);
  background: var(--line-soft);
}

.md-callout-title {
  display: block;
  margin-bottom: var(--space-2);
  color: var(--blue);
}

.md-callout > :last-child {
  margin-bottom: 0;
}

.md-details {
  margin: var(--space-4) 0;
  border: 1px solid var(--line);
  padding: var(--space-3) var(--space-4);
}

.md-details summary {
  cursor: pointer;
  font-weight: 700;
  color: var(--blue);
}

.md-details[open] summary {
  margin-bottom: var(--space-3);
}

/* Titles and document names typed in the admin panel: a long compound word
   or a pasted address wraps inside its column instead of widening it past
   the edge of a phone screen; no hyphen is added inside a word (a word is
   split only when it is wider than the whole line). */
.page-h1,
.news-card-title,
.news-lead-title,
.news-row-title,
.news-opening-title,
.news-more-title,
.document-row-title,
.site-section-title,
.album-card-title,
.home-gallery-title,
.chp-title,
.chp-news-title,
.chp-doc-link {
  overflow-wrap: break-word;
  hyphens: manual;
}

hr {
  border: 0;
  border-top: 1px solid var(--line);
  margin: var(--space-7) 0;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* Low-vision theme. The type scale itself is redefined in tokens.css; these
   are the reading and meta sizes the component files write as literals, off
   the scale, raised to the same steps: 20px+ for text, 15px for meta lines. */
:root[data-theme='low-vision'] .news-article-body {
  font-size: 22px;
}

:root[data-theme='low-vision'] .news-opening-lead,
:root[data-theme='low-vision'] .news-reading .news-article-body > p:first-child {
  font-size: 23px;
}

:root[data-theme='low-vision'] .news-card-title {
  font-size: 23px;
}

:root[data-theme='low-vision'] .news-row-title {
  font-size: 27px;
}

:root[data-theme='low-vision'] .site-footer,
:root[data-theme='low-vision'] .news-lead-summary,
:root[data-theme='low-vision'] .chp-news-summary,
:root[data-theme='low-vision'] .chp-doc-link,
:root[data-theme='low-vision'] .document-row-title,
:root[data-theme='low-vision'] .news-rail-item,
:root[data-theme='low-vision'] .section-report-table table {
  font-size: 20px;
}

:root[data-theme='low-vision'] .footer-bottom,
:root[data-theme='low-vision'] .footer-col h2,
:root[data-theme='low-vision'] .form-group label,
:root[data-theme='low-vision'] .field-error,
:root[data-theme='low-vision'] .news-card-date,
:root[data-theme='low-vision'] .news-section-title,
:root[data-theme='low-vision'] .news-lead-kicker,
:root[data-theme='low-vision'] .news-flag,
:root[data-theme='low-vision'] .news-opening .breadcrumbs,
:root[data-theme='low-vision'] .news-opening-kicker,
:root[data-theme='low-vision'] .news-opening-meta,
:root[data-theme='low-vision'] .news-article-byline,
:root[data-theme='low-vision'] .news-linked-pages,
:root[data-theme='low-vision'] .news-share-link,
:root[data-theme='low-vision'] .news-cover figcaption,
:root[data-theme='low-vision'] .news-article-body figcaption,
:root[data-theme='low-vision'] .chp-chip,
:root[data-theme='low-vision'] .chp-chip-count,
:root[data-theme='low-vision'] .chp-doc-type,
:root[data-theme='low-vision'] .chp-year-count,
:root[data-theme='low-vision'] .chp-news-month,
:root[data-theme='low-vision'] .page-opening-counter,
:root[data-theme='low-vision'] .section-report-kicker,
:root[data-theme='low-vision'] .section-report-table th {
  font-size: 15px;
}

/* A side menu's title is never smaller than the links under it. */
:root[data-theme='low-vision'] .section-nav-title {
  font-size: var(--fs-nav-side);
}

/* Photos and embedded maps/videos stay — a gallery without its photos is an
   empty page, and CSS cannot put an image's alt text in its place — but lose
   their colour, so they do not compete with the yellow-on-black text. The
   school's logo too, like every other picture (QA, 2026-10). */
:root[data-theme='low-vision'] img,
:root[data-theme='low-vision'] iframe {
  filter: grayscale(1);
}

/* Headings without negative tracking, whatever a template set: the word
   spaces of a heavy weight nearly close at the low-vision sizes. */
:root[data-theme='low-vision'] :is(h1, h2, h3, h4, .page-h1, .hero-title) {
  letter-spacing: 0;
}

/* The credit line at the very bottom of every template's footer
   (partials/site-credit.liquid): the footer's small print — its quiet text
   colour on the dark band, --muted on a light one — with the link in the
   same colour, told apart by its underline. Every pair reads at 4.5:1
   (test/templates/siteCredit.test.js); a template whose footer is always
   dark sets its own colour back for the light variant. */
.site-footer .site-credit {
  color: var(--chrome-bar-ink);
  font-size: var(--fs-meta-lg);
}

.theme-footer-light .site-footer .site-credit {
  color: var(--muted);
}

.site-footer p + .site-credit {
  margin-top: var(--space-2);
}

.site-footer p.site-credit a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 0.15em;
}

/* Print: the page's own content only — no site frame, and none of the
   screen-only reading aids (progress bar, chapter bar, share links, the
   report-list link, the latest-post flag). Loaded before every component
   file, hence !important against their display. */
@media print {
  .topbar,
  .site-header,
  .mobile-menu-overlay,
  .announcement,
  .site-footer,
  .section-nav,
  [data-section-nav],
  [data-print],
  .section-report-tools,
  .section-report-back,
  .section-report-kicker,
  .meals-daypage .meals-calendar,
  .reading-progress,
  .chp-bar,
  .chp-report-link,
  .chp-news-flag,
  .portal-feed-flag,
  .news-share {
    display: none !important;
  }

  /* The space under the page's last line is not printed: the templates' padding under <main> is
     large in low-vision mode and pushed an empty sheet after the text. */
  main {
    padding-bottom: 0 !important;
  }
}

/* The section nav's row on a phone (public/js/section-nav.js): a side with
   more links out of sight fades out, so the row reads as one that scrolls. */
@media (max-width: 899px) {
  [data-section-nav].has-more-after ul {
    -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 32px), transparent);
    mask-image: linear-gradient(90deg, #000 calc(100% - 32px), transparent);
  }

  [data-section-nav].has-more-before ul {
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 32px);
    mask-image: linear-gradient(90deg, transparent, #000 32px);
  }

  [data-section-nav].has-more-before.has-more-after ul {
    -webkit-mask-image: linear-gradient(
      90deg,
      transparent,
      #000 32px,
      #000 calc(100% - 32px),
      transparent
    );
    mask-image: linear-gradient(90deg, transparent, #000 32px, #000 calc(100% - 32px), transparent);
  }
}

/* The low-vision switch (partials/bvi-toggle) names the action: «Для
   слабозорих» in the regular look, «Звичайна версія» in the low-vision one.
   Keyed on the theme zir.js sets before the first paint, so the right label
   is there at once; the hidden one is not part of the button's name. */
.bvi-label-on {
  display: none;
}

:root[data-theme='low-vision'] .bvi-label-off {
  display: none;
}

:root[data-theme='low-vision'] .bvi-label-on {
  display: inline;
}

/* The low-vision switch is a GET form without a script (partials/bvi-toggle):
   it takes no box of its own, so its button sits where it always did. */
.bvi-form {
  display: contents;
}

/* The menu without JavaScript (partials/mobile-menu). The overlay is in the
   markup, not hidden. zir.js puts `js` on <html> in <head>, before the first
   paint: with it the overlay stays out of sight until mobile-menu.js has
   closed it and wired its buttons (.is-ready); without it the overlay is the
   plain list that follows the header — search, links, every dropdown's pages
   shown — and the buttons that need a script (open, close, a group's own)
   are not offered. Each stylesheet family ends the list at the width where
   its header shows the whole menu (chrome.css, base-template.css). */
html.js .mobile-menu-overlay:not(.is-ready) {
  display: none;
}

html:not(.js) .mobile-menu-overlay {
  position: static;
  z-index: auto;
  overflow: visible;
  padding: var(--space-5);
  border-bottom: 1px solid var(--line);
}

html:not(.js) .mobile-menu-toggle,
html:not(.js) .mobile-menu-close {
  display: none;
}

html:not(.js) .mobile-about-toggle:disabled {
  color: var(--ink);
  cursor: default;
}

/* css/components/doc-viewer.css */
/* A document shown page by page (/dokument/<file id>): the title block, the page in a frame with
   a step link on each side, the list of pages. Colours, spaces and sizes come from the tokens,
   so it follows every template's look and the low-vision mode. */
.doc-viewer {
  padding-bottom: var(--space-11);
}

.doc-viewer-date {
  margin: var(--space-1) 0 0;
  color: var(--muted);
  font-size: var(--fs-meta-lg);
}

.doc-viewer-desc {
  max-width: 62ch;
  margin: var(--space-3) 0 0;
  color: var(--body);
  font-size: var(--fs-text);
  line-height: var(--lh-text);
}

/* Only on paper: where the document lives. */
.doc-viewer-address {
  display: none;
}

.doc-viewer-message {
  max-width: 62ch;
  margin: var(--space-7) 0 0;
  padding: var(--space-4) var(--space-5);
  border: 1px solid var(--line-strong);
  color: var(--ink);
  font-size: var(--fs-text);
}

.doc-viewer-nav {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: var(--space-3);
  max-width: 900px;
  margin: var(--space-5) 0;
  font-size: var(--fs-nav);
}

.doc-viewer-step {
  padding: var(--space-2) 0;
  color: var(--accent);
  font-weight: 700;
}

.doc-viewer-step:last-child {
  text-align: right;
}

.doc-viewer-step--off {
  visibility: hidden;
}

.doc-viewer-status {
  color: var(--body);
  text-align: center;
}

.doc-viewer-stage {
  max-width: 900px;
  margin: 0;
  border: 1px solid var(--line-strong);
  background: var(--paper);
}

.doc-viewer-page {
  display: block;
  width: 100%;
  height: auto;
}

.doc-viewer-pages {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  max-width: 900px;
  margin: var(--space-5) 0 0;
  padding: 0;
  list-style: none;
}

.doc-viewer-num {
  display: block;
  min-width: 44px;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--line-strong);
  color: var(--accent);
  font-size: var(--fs-nav);
  text-align: center;
}

.doc-viewer-num[aria-current='page'] {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--paper);
  font-weight: 700;
}

/* The low-vision mode: the page takes the whole width. */
:root[data-theme='low-vision'] .doc-viewer-nav,
:root[data-theme='low-vision'] .doc-viewer-stage,
:root[data-theme='low-vision'] .doc-viewer-pages,
:root[data-theme='low-vision'] .doc-viewer-desc {
  max-width: none;
}

/* Paper: the title, the description and the address; not the pages. */
@media print {
  .doc-viewer-nav,
  .doc-viewer-stage,
  .doc-viewer-list,
  .doc-viewer-message {
    display: none !important;
  }

  .doc-viewer-address {
    display: block;
    margin-top: var(--space-5);
  }
}

/* css/components/md-blocks.css */
/* Blocks of the visual editor (story 24.3), emitted by
   src/lib/markdownSyntax.js: the three kinds of notice and the photo grid
   inside a text. The plain .md-callout and every older block stay in
   base.css. */

.md-callout-info {
  border-left-color: var(--blue);
  background: var(--line-soft);
}

.md-callout-warning {
  border-left-color: var(--callout-warning);
  background: var(--callout-warning-bg);
}

.md-callout-warning .md-callout-title {
  color: var(--callout-warning);
}

.md-callout-success {
  border-left-color: var(--callout-success);
  background: var(--callout-success-bg);
}

.md-callout-success .md-callout-title {
  color: var(--callout-success);
}

/* A gallery inside a text reuses the album grid (.masonry-gallery), so the
   album viewer opens its photos; three columns fit the text column better than
   the album page's four. */
.md-gallery {
  grid-template-columns: repeat(3, 1fr);
  margin: var(--space-5) 0;
}

.md-gallery .album-photo {
  width: auto;
}

@media (max-width: 600px) {
  .md-gallery {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* Low vision: every notice is the same black box with a yellow edge — the
   three kinds keep their title, not their colour. */
:root[data-theme='low-vision'] .md-callout,
:root[data-theme='low-vision'] .md-callout-info,
:root[data-theme='low-vision'] .md-callout-warning,
:root[data-theme='low-vision'] .md-callout-success {
  border: 2px solid var(--accent);
  border-left-width: 6px;
  background: var(--paper);
  color: var(--ink);
}

:root[data-theme='low-vision'] .md-callout-title {
  color: var(--accent);
}

/* The button of «@кнопка» (growth story 31, decision G): white words on the
   accent, darker under the pointer, never underlined. [href] makes the rule
   one step more specific than a template's «text links» rule (.x-prose a),
   which used to paint the words in the link colour on the accent — the
   button was unreadable in «Панорама». */
.md-button[href],
.md-button[href]:visited {
  display: inline-block;
  padding: var(--space-3) var(--space-6);
  border: 1.5px solid var(--accent);
  background: var(--accent);
  color: var(--paper);
  font-weight: 700;
  text-decoration: none;
}

.md-button[href]:hover,
.md-button[href]:focus-visible {
  border-color: var(--blue);
  background: var(--blue);
  color: var(--paper);
  text-decoration: none;
}

/* Low vision: yellow words and frame on black, the page's own colours. */
:root[data-theme='low-vision'] .md-button[href],
:root[data-theme='low-vision'] .md-button[href]:visited,
:root[data-theme='low-vision'] .md-button[href]:hover {
  border: 2px solid var(--accent);
  background: var(--paper);
  color: var(--accent);
  text-decoration: underline;
}

/* The text palette (story 32, B3, src/config/palette.js): a coloured word is
   <span class="c-<key>">, a highlight <mark class="fill-<key>">, a filled table
   cell <td class="fill-<key>">. Classes only, never a style attribute; the
   colours are tokens, so the low-vision mode turns them yellow and the fills
   transparent (tokens.css), and the school's two follow «Оформлення». */
.c-black {
  color: var(--pal-black);
}

.c-grey {
  color: var(--pal-grey);
}

.c-red {
  color: var(--pal-red);
}

.c-orange {
  color: var(--pal-orange);
}

.c-green {
  color: var(--pal-green);
}

.c-blue {
  color: var(--pal-blue);
}

.c-violet {
  color: var(--pal-violet);
}

.c-brown {
  color: var(--pal-brown);
}

.c-primary {
  color: var(--blue);
}

.c-accent {
  color: var(--accent);
}

/* A highlight keeps the text's own colour: the fills are light enough for
   the ink, the body text and the colour itself at 4.5:1. */
mark[class*='fill-'] {
  padding: 0 0.1em;
  color: inherit;
}

.fill-black,
.md-table .fill-black {
  background: var(--pal-black-tint);
}

.fill-grey,
.md-table .fill-grey {
  background: var(--pal-grey-tint);
}

.fill-red,
.md-table .fill-red {
  background: var(--pal-red-tint);
}

.fill-orange,
.md-table .fill-orange {
  background: var(--pal-orange-tint);
}

.fill-green,
.md-table .fill-green {
  background: var(--pal-green-tint);
}

.fill-blue,
.md-table .fill-blue {
  background: var(--pal-blue-tint);
}

.fill-violet,
.md-table .fill-violet {
  background: var(--pal-violet-tint);
}

.fill-brown,
.md-table .fill-brown {
  background: var(--pal-brown-tint);
}

.fill-primary,
.md-table .fill-primary {
  background: var(--primary-tint);
}

.fill-accent,
.md-table .fill-accent {
  background: var(--accent-tint);
}

/* Low vision: the fill is gone, so a highlighted word turns yellow instead —
   it still stands out from the white text around it. */
:root[data-theme='low-vision'] mark[class*='fill-'] {
  color: var(--accent);
}

/* A table with its own look (story 32, B1): the editor writes it as an HTML
   table inside .md-table — alignment, borders and fill per cell, the
   borders of the whole table. Two classes deep, one step above base.css's
   ".md-table th/td". A cell's own border is 2px, so in the collapsed
   table it wins over its neighbours' 1px lines. */
.md-table .cell-l {
  text-align: left;
}

.md-table .cell-c {
  text-align: center;
}

.md-table .cell-r {
  text-align: right;
}

.md-table .tbl-borders-dashed th,
.md-table .tbl-borders-dashed td {
  border-style: dashed;
  border-color: var(--line-strong);
}

.md-table .tbl-borders-none th,
.md-table .tbl-borders-none td {
  border-style: none;
}

.md-table .cell-border-solid {
  border: 2px solid var(--line-strong);
}

.md-table .cell-border-dashed {
  border: 2px dashed var(--line-strong);
}

.md-table .cell-border-none {
  border-style: hidden;
}

/* css/components/album.css */
/* The album (GitHub #201, #207; partials/album, album-thumbs, album-viewer
   and public/js/album.js): one framed photo at a time with ‹ › on the
   frame, its caption under it and the matrix of thumbnails under that, and
   the full-screen viewer. Every page template links this file; a template's
   own colours, faces and corners arrive through the tokens. Low vision: the
   photos are grey by base.css, the controls yellow on black (below). */

.album {
  margin: var(--space-7) 0;
}

.album-head {
  margin-bottom: var(--space-3);
}

.album-title {
  margin: 0;
  color: var(--ink);
  font-size: var(--fs-card-title);
  line-height: var(--lh-h3);
}

.album-title a {
  color: inherit;
}

.album-meta,
.album-source {
  margin: var(--space-1) 0 0;
  color: var(--muted);
  font-size: var(--fs-meta-lg);
}

/* Over the cards of a chapter's albums that are not in place. */
.album-more-title {
  margin: var(--space-7) 0 var(--space-4);
  color: var(--ink);
  font-size: var(--fs-card-title);
  line-height: var(--lh-h3);
}

.album-source a {
  color: var(--accent);
  font-weight: 600;
}

/* Who took a photo (growth story 34): «Фото: …» on its own line under a
   caption, an album's title or a slide, smaller than the caption itself. */
.photo-credit {
  display: block;
  font-size: var(--fs-meta-sm);
  font-style: normal;
}

/* The stage: ONE photo in a 3:2 frame. The slides stand side by side in the
   strip and the stage shows exactly one of them — the script moves the strip
   (a transform), nothing scrolls sideways. ‹ ›, the counter and «На весь
   екран» lie on the frame: .album-controls is as tall as the frame (its
   padding is two thirds of the stage's width) and lets clicks through. */
.album-stage {
  position: relative;
  max-width: 800px;
  overflow: hidden;
  /* Brought into view by a thumbnail: clear of the sticky header (and of a
     section page's chapter bar). */
  scroll-margin-top: var(--chp-offset, 96px);
}

.album-track {
  display: flex;
  margin: 0;
  padding: 0;
  list-style: none;
  touch-action: pan-y;
  transition: transform 0.35s ease;
}

.album-track--jump {
  transition: none;
}

.album-slide {
  flex: 0 0 100%;
  min-width: 0;
  margin: 0;
  padding: 0;
}

.album-figure {
  margin: 0;
}

.album-frame {
  display: block;
  aspect-ratio: 3 / 2;
  overflow: hidden;
  border-radius: var(--radius-media);
  background: var(--paper-2);
}

.album-frame:focus-visible,
.album-thumb:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: -3px;
}

.album-img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.album--ready .album-frame,
.album-zoom {
  cursor: zoom-in;
}

.album-caption {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: var(--space-2);
  color: var(--body);
  font-size: var(--fs-text);
  line-height: var(--lh-h3);
}

.album-caption-note {
  color: var(--muted);
  font-size: var(--fs-meta-lg);
}

.album-caption-album {
  color: var(--accent);
  font-weight: 600;
}

.album-controls {
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  height: 0;
  padding-top: 66.6667%;
  pointer-events: none;
}

.album-btn,
.album-counter {
  position: absolute;
  pointer-events: auto;
}

.album-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 1px solid var(--chrome-bar-line);
  border-radius: var(--radius-button);
  background: var(--blue-950-a92);
  color: var(--chrome-bar-strong);
  font: inherit;
  font-size: 28px;
  line-height: 1;
  cursor: pointer;
}

.album-btn--prev,
.album-btn--next {
  top: 50%;
  translate: 0 -50%;
}

.album-btn--prev {
  left: var(--space-3);
}

.album-btn--next {
  right: var(--space-3);
}

.album-btn--full {
  right: var(--space-3);
  bottom: var(--space-3);
  width: auto;
  height: 40px;
  padding: 0 var(--space-3);
  font-size: var(--fs-meta-lg);
  font-weight: 600;
}

.album-btn:hover,
.album-btn:focus-visible {
  border-color: var(--accent-light);
  color: var(--accent-light);
}

.album-btn:focus-visible {
  outline: 3px solid var(--accent-light);
  outline-offset: 2px;
}

.album-btn:disabled {
  opacity: 0.35;
  cursor: default;
}

.album-btn[hidden],
.album-counter[hidden] {
  display: none;
}

.album-counter {
  bottom: var(--space-3);
  left: var(--space-3);
  margin: 0;
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-button);
  background: var(--blue-950-a92);
  color: var(--chrome-bar-strong);
  font-size: var(--fs-meta-lg);
  font-variant-numeric: tabular-nums;
  line-height: 1.3;
  pointer-events: none;
}

/* The matrix of thumbnails under the frame: small squares, the framed photo
   marked. */
.album-thumbs {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: var(--space-2);
  max-width: 800px;
  margin: var(--space-4) 0 0;
  padding: 0;
  list-style: none;
}

.album-thumbs-item {
  margin: 0;
}

.album-thumb {
  display: block;
  aspect-ratio: 1;
  overflow: hidden;
  border-radius: var(--radius-media);
  background: var(--paper-2);
}

.album-thumb img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.85;
}

.album-thumb:hover img,
.album-thumb[aria-current='true'] img {
  opacity: 1;
}

.album-thumb[aria-current='true'] {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
}

/* An album in place: «Усі N фото →» under its matrix. */
.album-all-line {
  margin: var(--space-3) 0 0;
}

.album-all {
  color: var(--accent);
  font-size: var(--fs-text);
  font-weight: 700;
}

@media (max-width: 899px) {
  .album-thumbs {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

@media (max-width: 599px) {
  .album-thumbs {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .album-btn--prev {
    left: var(--space-2);
  }

  .album-btn--next {
    right: var(--space-2);
  }
}

/* The viewer: the page's dark band behind the photo, the stage snapping to
   each photo, the caption, and a strip of thumbnails at the bottom. */
.album-viewer-open {
  overflow: hidden;
}

.album-viewer {
  position: fixed;
  z-index: 1000;
  inset: 0;
  display: flex;
  flex-direction: column;
  background: linear-gradient(var(--blue-950-a92), var(--blue-950-a92)), var(--chrome-bar);
  color: var(--chrome-bar-strong);
}

.album-viewer[hidden] {
  display: none;
}

.album-viewer-top {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
}

.album-viewer-title {
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
  overflow: hidden;
  color: inherit;
  font-size: var(--fs-text);
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.album-viewer-counter {
  margin: 0;
  color: var(--chrome-bar-ink);
  font-size: var(--fs-meta-lg);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.album-viewer-btn {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  padding: 0;
  border: 1px solid var(--chrome-bar-line);
  border-radius: var(--radius-button);
  background: var(--blue-950-a50);
  color: var(--chrome-bar-strong);
  font: inherit;
  font-size: 28px;
  line-height: 1;
  cursor: pointer;
}

.album-viewer-btn:hover,
.album-viewer-btn:focus-visible {
  border-color: var(--accent-light);
  color: var(--accent-light);
}

.album-viewer-btn:focus-visible,
.album-viewer-stage:focus-visible,
.album-viewer-thumb:focus-visible,
.album-viewer-more a:focus-visible {
  outline: 3px solid var(--accent-light);
  outline-offset: -3px;
}

.album-viewer-btn:disabled {
  opacity: 0.4;
  cursor: default;
}

.album-viewer-main {
  position: relative;
  display: flex;
  flex: 1 1 auto;
  min-height: 0;
}

.album-viewer-stage {
  position: relative;
  display: flex;
  flex: 1 1 auto;
  margin: 0;
  padding: 0;
  list-style: none;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  overscroll-behavior: contain;
  scrollbar-width: none;
}

/* A swipe down closes the viewer; sideways and pinch stay the browser's. */
@supports (touch-action: pan-x pinch-zoom) {
  .album-viewer-stage {
    touch-action: pan-x pinch-zoom;
  }
}

.album-viewer-slide {
  display: flex;
  flex: 0 0 100%;
  align-items: center;
  justify-content: center;
  height: 100%;
  margin: 0;
  padding: 0 var(--space-2);
  scroll-snap-align: start;
  scroll-snap-stop: always;
}

.album-viewer-slide img {
  display: block;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

.album-viewer-more a {
  color: var(--chrome-bar-strong);
  font-size: var(--fs-card-title);
  font-weight: 700;
}

.album-viewer-go {
  position: absolute;
  top: 50%;
  translate: 0 -50%;
}

.album-viewer-go--prev {
  left: var(--space-4);
}

.album-viewer-go--next {
  right: var(--space-4);
}

.album-viewer-info {
  max-width: 70ch;
  margin: 0 auto;
  padding: var(--space-2) var(--space-4) 0;
  text-align: center;
}

.album-viewer-caption,
.album-viewer-note {
  margin: 0;
  line-height: var(--lh-h3);
}

.album-viewer-caption {
  font-size: var(--fs-text);
}

.album-viewer-note {
  color: var(--chrome-bar-ink);
  font-size: var(--fs-meta-lg);
}

.album-viewer-note a {
  color: var(--chrome-bar-strong);
  text-decoration: underline;
}

.album-viewer-caption[hidden],
.album-viewer-note[hidden] {
  display: none;
}

.album-viewer-strip {
  position: relative;
  display: flex;
  flex: 0 0 auto;
  gap: var(--space-1);
  margin: 0;
  padding: var(--space-3) var(--space-4);
  list-style: none;
  overflow-x: auto;
  scrollbar-width: thin;
}

.album-viewer-strip li {
  flex: 0 0 auto;
  margin: 0;
}

.album-viewer-strip li:first-child {
  margin-left: auto;
}

.album-viewer-strip li:last-child {
  margin-right: auto;
}

.album-viewer-thumb {
  display: block;
  width: 64px;
  height: 64px;
  padding: 0;
  border: 2px solid transparent;
  background: transparent;
  cursor: pointer;
  opacity: 0.7;
}

.album-viewer-thumb img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.album-viewer-thumb:hover,
.album-viewer-thumb[aria-current='true'] {
  opacity: 1;
}

.album-viewer-thumb[aria-current='true'] {
  border-color: var(--accent-light);
}

@media (max-width: 767px) {
  .album-viewer-top {
    padding: var(--space-2) var(--space-3);
  }

  .album-viewer-go--prev {
    left: var(--space-2);
  }

  .album-viewer-go--next {
    right: var(--space-2);
  }

  .album-viewer-slide {
    padding: 0;
  }

  .album-viewer-strip {
    padding: var(--space-2) var(--space-3);
  }

  .album-viewer-thumb {
    width: 48px;
    height: 48px;
  }
}

/* Low vision: the controls yellow on black, the current photo in yellow. */
:root[data-theme='low-vision'] .album-btn,
:root[data-theme='low-vision'] .album-viewer-btn {
  border-color: var(--accent);
  color: var(--accent);
}

:root[data-theme='low-vision'] .album-thumb img,
:root[data-theme='low-vision'] .album-viewer-thumb {
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .album-track {
    transition: none;
  }
}

/* «Усі фото» on the albums collection: one page of twelve photos as 4 × 3
   thumbnails, 3 columns on a tablet and 2 on a phone; a link to another of
   its pages opens at the section, clear of the sticky header. */
.album--matrix {
  scroll-margin-top: var(--chp-offset, 96px);
}

.album--matrix .album-thumbs {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

@media (max-width: 1023px) {
  .album--matrix .album-thumbs {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (max-width: 599px) {
  .album--matrix .album-thumbs {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* css/components/meals.css */
/* «Харчування» (growth stories 38, 54, 67): the week, one look in every template. Below 1200 px it is a
   list of days — each a heading line, then rows «photo | прийом and dishes», the photo above the
   dishes where they would keep less than 11rem beside it and, in low-vision mode, below 600 px;
   from 1200 px a table at most 60rem wide (a week of three or more прийоми stays the list), a photo in a cell at most 180 px, the calendar under it
   at the column's start. A template only recolours it and sets its faces (docs/dev/templates.md
   «Харчування»). The markup is partials/meals/week and partials/meals/cell; the home block
   «Харчування сьогодні» draws the same cells (the rules at the end). Print: no week or month arrows, a day
   is not split between sheets (the @media print block at the end). Order is the DOM's: no rule here
   reorders anything. */

/* «Меню» (story 54) is the last chapter: the information above it keeps the chapters' gap. */
.meals-info + .meals-menu {
  margin-top: var(--chp-gap);
}

.meals-empty {
  color: var(--muted);
}

.meals-week {
  max-width: 60rem;
  margin: 0 0 var(--space-8);
}

.meals-weeknav {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-2) var(--space-3);
  margin: 0 0 var(--space-3);
}

.meals-weeknav-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  min-height: 44px;
  color: var(--accent);
  font-weight: 600;
}

.meals-weeknav-link--next {
  margin-inline-start: auto;
}

/* The group filter above the week (from three groups): links wrapping on a phone, each at least
   44 px high; the current one is told by weight and a heavier border, not by colour alone. */
.meals-groups {
  margin: 0 0 var(--space-3);
}

.meals-groups-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

.meals-groups-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 var(--space-4);
  border: 1px solid var(--line);
  color: var(--accent);
  font-weight: 600;
  overflow-wrap: break-word;
  min-width: 0;
  max-width: 100%;
}

.meals-groups-link[aria-current='page'] {
  border: 3px solid var(--ink);
  color: var(--ink);
  font-weight: 800;
}

.meals-scroll {
  margin: 0 0 var(--space-7);
}

.meals-table {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
  color: var(--body);
}

.meals-caption {
  margin: 0 0 var(--space-3);
  color: var(--ink);
  font-family: var(--font-heading);
  font-size: var(--fs-card-title);
  font-weight: 700;
  line-height: var(--lh-h3);
  text-align: left;
  overflow-wrap: break-word;
  /* A sentence, not a column: lining figures, so an old-style «1» never reads as «I». */
  font-variant-numeric: lining-nums;
}

.meals-table th,
.meals-table td {
  padding: var(--space-4) var(--space-3);
  border-top: 1px solid var(--line);
  text-align: left;
  vertical-align: top;
  overflow-wrap: break-word;
  hyphens: manual;
}

.meals-head th {
  border-top: 0;
  border-bottom: 2px solid var(--line-strong);
  color: var(--ink);
  font-weight: 600;
}

.meals-head th:first-child {
  width: 9.5rem;
}

/* The root is 20 px in low-vision mode: the day column keeps what its words need, so the dish
   columns keep the rest. */
:root[data-theme='low-vision'] .meals-head th:first-child {
  width: 7.5rem;
}

.meals-day {
  border-inline-start: 3px solid transparent;
  color: var(--ink);
  font-weight: 600;
}

.meals-day-name,
.meals-day-date {
  display: block;
}

.meals-day-name::first-letter {
  text-transform: uppercase;
}

.meals-day-date {
  color: var(--muted);
  font-size: var(--fs-meta-lg);
  font-weight: 400;
}

.meals-today {
  display: inline-block;
  margin-top: var(--space-1);
  color: var(--accent);
  font-size: var(--fs-meta-lg);
  font-weight: 700;
}

.meals-row.is-today .meals-day {
  border-inline-start-color: var(--accent);
}

.meals-td--note {
  color: var(--muted);
  font-size: var(--fs-text);
}

.meals-row--none .meals-day,
.meals-row--none .meals-td {
  padding-block: var(--space-2);
}

/* The cell's width, not base.css's shrink-to-fit figure (which takes the picture's `sizes` width). */
.meals-figure {
  width: auto;
  margin: 0 0 var(--space-3);
}

.meals-shot {
  position: relative;
  display: block;
  aspect-ratio: 4 / 3;
  margin: 0;
  overflow: hidden;
  background: var(--paper-2);
}

.meals-shot img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: inherit; /* follows the frame, not the 2px of `figure img` */
}

/* «+N» on the first photo: small, one line, so it covers a third of a 96 px photo at most. */
.meals-more {
  position: absolute;
  right: 4px;
  bottom: 4px;
  padding: 0 6px;
  background: var(--blue-shadow-a70);
  color: var(--chrome-bar-strong);
  font-size: var(--fs-meta-lg);
  font-weight: 700;
  line-height: 1.5;
  white-space: nowrap;
}

:root[data-theme='low-vision'] .meals-more {
  border: 1px solid var(--line-strong);
  background: var(--paper);
  color: var(--ink);
}

.meals-slot {
  display: none;
  margin: 0 0 var(--space-1);
  color: var(--ink);
  font-weight: 600;
}

.meals-dash {
  margin: 0;
  color: var(--muted);
}

.meals-group {
  margin: var(--space-3) 0 var(--space-1);
  color: var(--ink);
}

.meals-text > :first-child {
  margin-top: 0;
}

.meals-cell .meals-dishes {
  margin: 0;
  padding-left: 1.1em;
  font-size: var(--fs-text);
}

.meals-flag {
  margin: 0 0 var(--space-1);
  color: var(--muted);
  font-size: var(--fs-meta-sm);
  font-weight: 600;
}

@media (min-width: 1200px) {
  /* A photo in a cell: the day page's thumbnail size, the dishes under it. Scoped to the table: the
     home block draws the same cell. */
  .meals-table .meals-cell--photo .meals-figure {
    width: min(100%, 180px);
  }
}

/* Below 1200 px the week is the list of days. A column of the table must hold the longest dish word
   with the list's indent: measured on the school seed in all eight templates, from 768 px three
   columns cut «вермішелевий» up to 1112 px («Зошит»), two cut «фрикадельками» between 904 and 1008 px
   («Стенд», «Вітрина», «Зошит», low-vision too), where a side menu narrows the column. At 1200 px every
   template leaves a column at least 9 px more than its word needs with three прийоми (the narrowest is
   «Зошит», whose frame caps it at any width), 67 px with two. Scoped to the table: the home block draws
   the same cells. */
@media (max-width: 1199px) {
  .meals-table,
  .meals-table tbody,
  .meals-row,
  .meals-table th,
  .meals-table td {
    display: block;
  }

  /* The column heads stay for assistive technology; each cell names its прийом in the list. */
  .meals-head {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
  }

  .meals-table th,
  .meals-table td {
    border-top: 0;
  }

  .meals-row {
    border-top: 1px solid var(--line);
  }

  .meals-table .meals-day {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0 var(--space-3);
    padding: var(--space-4) var(--space-3) var(--space-2);
  }

  /* A block table keeps its caption a table-caption, as narrow as its words. */
  .meals-caption {
    display: block;
  }

  .meals-day-name,
  .meals-day-date {
    display: inline-block;
  }

  .meals-today {
    margin-top: 0;
  }

  .meals-table .meals-td {
    padding: var(--space-2) var(--space-3);
  }

  .meals-row--none .meals-day {
    padding-bottom: 0;
  }

  .meals-table .meals-figure {
    margin: 0;
  }

  .meals-table .meals-slot {
    display: block;
  }

  /* A прийом nobody filled is not drawn in the list, but not display: none either: that would drop
     the cell from the accessibility tree and the cells after it would be read under the wrong
     column head. Clipped like .sr-only, it is read as «немає запису». */
  .meals-table .meals-td--empty {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
  }
}

/* In the week's list the photo stands beside the text where the text keeps 11rem (the longest dish
   word of the school seed, «фрикадельками», needs about 10.3rem in the widest face), else above it, still 96 px wide, so the week is as long in
   every template — by the cell's own width, whatever the template's frame; in low-vision mode below
   600 px always above (large type), as wide as 180 px. */
@media (max-width: 1199px) {
  .meals-table .meals-cell--photo {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
    align-items: start;
  }

  .meals-table .meals-cell--photo .meals-figure {
    flex: 0 0 96px;
  }

  .meals-table .meals-cell--photo .meals-text {
    flex: 999 1 11rem;
    min-width: 0;
  }
}

@media (max-width: 599px) {
  :root[data-theme='low-vision'] .meals-table .meals-cell--photo {
    display: block;
  }

  :root[data-theme='low-vision'] .meals-table .meals-cell--photo .meals-figure {
    width: min(180px, 100%);
    margin-bottom: var(--space-3);
  }
}

/* A week of three or more прийоми (week.list) is the list at every width: from 1200 px the same
   rules under .meals-table--list (the markup keeps the table's roles). Below 1200 px the rules
   above already apply to it. */
@media (min-width: 1200px) {
  .meals-table--list,
  .meals-table--list tbody,
  .meals-table--list .meals-row,
  .meals-table--list th,
  .meals-table--list td {
    display: block;
  }

  .meals-table--list .meals-head {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
  }

  .meals-table--list th,
  .meals-table--list td {
    border-top: 0;
  }

  .meals-table--list .meals-row {
    border-top: 1px solid var(--line);
  }

  .meals-table--list .meals-day {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0 var(--space-3);
    padding: var(--space-4) var(--space-3) var(--space-2);
  }

  .meals-table--list .meals-caption {
    display: block;
  }

  .meals-table--list .meals-day-name,
  .meals-table--list .meals-day-date {
    display: inline-block;
  }

  .meals-table--list .meals-today {
    margin-top: 0;
  }

  .meals-table--list .meals-td {
    padding: var(--space-2) var(--space-3);
  }

  .meals-table--list .meals-row--none .meals-day {
    padding-bottom: 0;
  }

  .meals-table--list .meals-cell--photo {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
    align-items: start;
  }

  .meals-table--list .meals-cell--photo .meals-figure {
    flex: 0 0 96px;
    width: auto;
    margin: 0;
  }

  .meals-table--list .meals-cell--photo .meals-text {
    flex: 999 1 11rem;
    min-width: 0;
  }

  .meals-table--list .meals-slot {
    display: block;
  }

  .meals-table--list .meals-td--empty {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
  }
}

/* The week's photos follow the theme's corners, as the day page's do. */
.meals-table .meals-shot {
  border-radius: var(--radius-media);
}

/* Print: no arrows, a day stays whole; the week page keeps only the week — no calendar, no rows
   without a record, and (the collection page only; the day page shares `.meals`, not
   `.base-collection`) no lead, information chapters or «Меню» heading. The rest of
   the week from the menu (`.meals-upcoming`) is part of the week and stays. */
@media print {
  .meals-weeknav,
  .meals-groups,
  .meals-calnav,
  .meals-calendar,
  .meals-row--none {
    display: none !important;
  }

  .meals-row {
    break-inside: avoid;
  }

  .base-collection.meals .base-collection-intro,
  .base-collection.meals .meals-info,
  .base-collection.meals .meals-menu > .chp-head {
    display: none !important;
  }

  /* The space after the last table is not printed: in low-vision mode its tokens are large enough
     to push an empty sheet after the week. */
  .base-collection.meals,
  .base-collection.meals .meals-menu,
  .base-collection.meals .meals-week {
    margin-bottom: 0 !important;
    padding-bottom: 0 !important;
  }
}

/* The home block «Харчування сьогодні» (story 54, slice 7): today's прийоми as the week's cells under
   their names — side by side from a cell of about 9.5rem (so also in the narrow column of «Газета» and
   «Портал»), one under another on a phone. */

.meals-dishes {
  margin: var(--space-3) 0 0;
  padding-left: var(--space-6);
  color: var(--body);
}

.meals-home {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 9.5rem), 1fr));
  gap: var(--space-6) var(--space-5);
}

@media (max-width: 599px) {
  .meals-home {
    grid-template-columns: minmax(0, 1fr);
  }
}

.meals-home-item {
  min-width: 0;
}

.meals-home .meals-dishes {
  margin-top: var(--space-2);
  padding-left: var(--space-5);
  overflow-wrap: break-word;
}

.meals-home-title {
  margin: 0 0 var(--space-2);
  color: var(--ink);
  font-size: var(--fs-text);
  font-weight: 600;
}

/* The heading above names the прийом; the cell's own name is for the week's list. */
.meals-home .meals-slot {
  display: none;
}

.meals-home .meals-cell--photo {
  display: block;
}

.meals-home .meals-figure {
  margin: 0 0 var(--space-3);
}

/* The home block's photos follow «Кути»; «Газета» and «Стенд» declare square ones. */
.meals-home .meals-shot {
  border-radius: var(--radius-media);
}

/* A day's link in the week. */

.meals-day-link {
  color: inherit;
  text-decoration: none;
}

.meals-day-link .meals-day-name {
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* The home block's date line reads at the body size. */
.base-block--meals .base-meta {
  font-size: var(--fs-text);
}

/* A day at its own address (growth story 61): one narrow sheet, the same on every template and every
   screen — the date, the share row, then a short block per прийом (its name, 4:3 thumbnails, the dishes).
   A template may only recolour it and set the прийом name's face. */
.meals-daypage {
  max-width: 40rem;
}

:root[data-theme='low-vision'] .meals-daypage {
  max-width: 800px;
}

.meals .meals-daypage .base-kicker {
  margin: 0 0 var(--space-1);
  color: var(--muted);
  font-size: var(--fs-meta-lg);
  font-weight: 600;
  letter-spacing: normal;
  text-transform: none;
}

.base-page.meals .meals-daypage .page-h1 {
  margin-top: 0;
  padding-top: 0;
  font-size: var(--fs-h2-phone);
  line-height: var(--lh-h2);
}

.meals .meals-daypage .base-kicker .meals-today {
  margin: 0;
  font-size: inherit;
}

:root[data-theme='low-vision'] .base-page.meals .meals-daypage .page-h1 {
  font-size: 30px;
  line-height: var(--lh-h2);
}

/* Sending is the first action: the button and the address side by side, wrapping on a phone. */
.meals-dayshare {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-4);
  margin: var(--space-4) 0 var(--space-6);
}

.meals-dayshare-button {
  min-height: 44px;
  padding: 0 var(--space-5);
  border: 1px solid var(--accent);
  background: transparent;
  color: var(--accent);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}

.meals-dayshare-button[hidden] {
  display: none;
}

/* The post's two messenger links beside the button: the same box, a 44 px target. */
.meals-dayshare-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 44px;
  padding: 0 var(--space-4);
  border: 1px solid var(--accent);
  color: var(--accent);
  font-weight: 600;
  text-decoration: none;
}

.meals-dayshare-link svg {
  width: 18px;
  height: 18px;
  flex: none;
}

/* «Меню групи …» / «Усі групи» under the share row of a filtered day. */
.meals-dayfilter {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1) var(--space-4);
  margin: 0 0 var(--space-5);
  color: var(--ink);
  font-weight: 600;
}

.meals-dayshare-url {
  font-size: var(--fs-meta-lg);
  color: var(--muted);
  overflow-wrap: break-word;
  min-width: 0;
}

.meals-dayblock {
  margin: 0 0 var(--space-5);
}

.meals-dayblock + .meals-dayblock {
  padding-top: var(--space-5);
  border-top: 1px solid var(--line);
}

/* 22 px (26 in low-vision): a step above the 16.5 px dishes in every template's heading face, still
   below the 24 px date. */
.meals-dayblock-title {
  margin: 0 0 var(--space-3);
  color: var(--ink);
  font-family: var(--font-heading);
  font-size: var(--fs-tagline);
  line-height: var(--lh-h3);
}

/* A block with photos and dishes: the name over the row, the thumbnails in the first column, the
   dishes in the second. The photo column is 128 px on a phone (about two dish lines), never more
   than 40% of the block so the dishes keep room on a narrow template, and 180 px (about three
   lines) from a tablet and in low-vision mode. */
.meals-dayblock--photos {
  display: grid;
  grid-template-columns: min(128px, 40%) minmax(0, 1fr);
  gap: var(--space-3) var(--space-4);
}

@media (min-width: 768px) {
  .meals-dayblock--photos {
    grid-template-columns: 180px minmax(0, 1fr);
  }
}

:root[data-theme='low-vision'] .meals-dayblock--photos {
  grid-template-columns: 180px minmax(0, 1fr);
}

.meals-dayblock--photos .meals-dayblock-title {
  grid-column: 1 / -1;
  margin: 0;
}

.meals-daythumbs {
  display: grid;
  align-content: start;
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.meals-dayblock--bare .meals-daythumbs,
.meals-dayblock--above .meals-daythumbs {
  display: flex;
  flex-wrap: wrap;
}

/* More photos than dishes: the photos in a row above the dishes, sized like a block without dishes. */
.meals-dayblock--above .meals-daythumbs {
  margin-bottom: var(--space-3);
}

/* A 4:3 crop as wide as its column or list item; the border is inside the size. */
.meals-daythumbs a {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  border: 1px solid var(--line);
  border-radius: var(--radius-media);
  overflow: hidden;
}

.meals-daythumbs img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.meals-daythumbs a:focus-visible {
  outline: var(--focus-ring, 2px solid var(--accent));
  outline-offset: 2px;
}

/* Without dishes: up to 180 px, never wider than half the row, so two always fit side by side. */
.meals-dayblock--bare .meals-daythumbs li,
.meals-dayblock--above .meals-daythumbs li {
  width: min(180px, calc(50% - var(--space-2) / 2));
}

/* Low-vision on a narrow screen: the dishes would get too little room beside the photos, so the
   photos become a wrapping row above them, sized like a block without dishes. */
@media (max-width: 599px) {
  :root[data-theme='low-vision'] .meals-dayblock--photos {
    display: block;
  }

  :root[data-theme='low-vision'] .meals-dayblock--photos .meals-dayblock-title {
    margin-bottom: var(--space-3);
  }

  :root[data-theme='low-vision'] .meals-dayblock--photos .meals-daythumbs {
    display: flex;
    flex-wrap: wrap;
    margin-bottom: var(--space-3);
  }

  :root[data-theme='low-vision'] .meals-dayblock--photos .meals-daythumbs li {
    width: min(180px, calc(50% - var(--space-2) / 2));
  }
}

.meals-daydishes {
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: var(--fs-text);
  line-height: var(--lh-text);
}

.meals-daydishes li {
  padding: 10px 0;
  border-top: 1px solid var(--line);
  color: var(--ink);
  overflow-wrap: break-word;
}

.meals-daydishes li:first-child {
  padding-top: 0;
  border-top: 0;
}

.meals-dish-detail {
  color: var(--muted);
}

/* The month calendar (story 54): a plain seven-column table under the page, weekend columns muted,
   a day with a record underlined and bold (never colour alone), today boxed. */
.meals-calendar {
  max-width: 28rem;
  margin: var(--space-7) 0 0;
}

.meals-calendar-title {
  margin: 0 0 var(--space-2);
  color: var(--ink);
  font-family: var(--font-heading);
  font-size: var(--fs-card-title);
  font-weight: 700;
  line-height: var(--lh-h3);
}

.meals-calendar-range {
  margin: 0 0 var(--space-3);
  color: var(--muted);
  font-size: var(--fs-meta-lg);
}

.meals-calnav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-5);
}

.meals-calnav-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  min-height: 44px;
  color: var(--accent);
  font-weight: 600;
}

.meals-calnav-link--next {
  margin-inline-start: auto;
}

.meals-cal {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
  color: var(--body);
}

.meals-cal-caption {
  margin: 0 0 var(--space-2);
  color: var(--ink);
  font-weight: 600;
  text-align: left;
}

.meals-cal th {
  padding: var(--space-2) 0;
  border-bottom: 2px solid var(--line-strong);
  color: var(--ink);
  font-size: var(--fs-meta-lg);
  font-weight: 600;
  text-align: center;
}

.meals-cal td {
  padding: 0;
  border-top: 1px solid var(--line);
  text-align: center;
}

.meals-cal .meals-cal-weekend {
  color: var(--muted);
}

.meals-cal-day {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: min(40px, 100%);
  min-height: 44px;
  margin: 0 auto;
}

.meals-cal-day--record {
  color: var(--accent);
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Today's box (keyed on the cell: the open day of a day's page is aria-current="page" and may be
   today too) gives way to the focus ring while focused. */
.is-today > .meals-cal-day:not(:focus-visible) {
  outline: 2px solid var(--ink);
  outline-offset: -4px;
}

/* The open day of a day's page: a fill, not colour alone, strong in both modes; today's box inside
   it is drawn in the page colour. */
.meals-cal-day[aria-current='page'] {
  background: var(--ink);
  color: var(--paper);
  text-decoration: none;
}

.is-today > .meals-cal-day[aria-current='page']:not(:focus-visible) {
  outline-color: var(--paper);
}

/* A day marked «Харчування не було» (growth story 54, slice 9): its row says so across the row, and
   its page opens with the same sentence instead of blocks. The templates restyle it in slice 8. */
.meals-td--closed {
  color: var(--ink);
  font-size: var(--fs-text);
  font-weight: 600;
}

.meals-closed {
  margin: 0 0 var(--space-5);
  padding: var(--space-2) var(--space-4);
  border-inline-start: 4px solid var(--line);
  color: var(--ink);
  font-size: var(--fs-text);
  font-weight: 600;
}

/* The allergen marks (growth story 72, S8a), drawn only where the school switched them on: a dish's
   mark under its name in the grey of the note, and the legend of the codes used under the menu — two
   columns, one on a phone. Text, never an icon or colour alone; printing keeps both. */
.meals-marks {
  display: block;
  color: var(--muted);
  font-size: var(--fs-meta-sm);
  line-height: var(--lh-text);
}

.meals-legend-box {
  margin: var(--space-5) 0 0;
  padding-top: var(--space-3);
  border-top: 1px solid var(--line);
  color: var(--ink);
}

.meals-legend-title,
.meals-legend-note {
  margin: 0 0 var(--space-2);
  color: var(--muted);
  font-size: var(--fs-meta-lg);
}

.meals-legend {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-1) var(--space-5);
  margin: 0 0 var(--space-2);
  font-size: var(--fs-meta-lg);
}

.meals-legend-item {
  display: flex;
  gap: var(--space-2);
}

.meals-legend-item dt {
  min-width: 2.2em;
  font-weight: 700;
}

.meals-legend-item dd {
  margin: 0;
}

@media (max-width: 599px) {
  .meals-legend {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* css/components/records.css */
/* Records on a page (growth story 39): the cards of a page's preset with their
   filter row, and a record's own page. The markup is partials/records-content
   and partials/record-body; every template links this file and its own
   colours, faces and corners arrive through the tokens. */

.records {
  margin-block: var(--space-8);
}

.records-title {
  margin: 0 0 var(--space-5);
  color: var(--ink);
  font-size: var(--fs-card-title);
}

.records-filters {
  margin: 0 0 var(--space-6);
}

.records-filter-label {
  margin: 0 0 var(--space-2);
  color: var(--muted);
  font-size: var(--fs-meta-lg);
}

.records-filter {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: 0 0 var(--space-3);
  padding: 0;
  list-style: none;
}

.records-chip {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 var(--space-5);
  border: 1.5px solid var(--line-strong);
  background: var(--paper);
  color: var(--ink);
  font-size: var(--fs-nav);
  text-decoration: none;
}

.records-chip--on {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--paper);
  font-weight: 600;
}

.records-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(240px, 100%), 1fr));
  gap: var(--space-6);
  margin: 0;
  padding: 0;
  list-style: none;
}

.records-card {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--line);
  background: var(--paper);
}

.records-card-photo {
  line-height: 0;
}

.records-card-photo img {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
}

.records-card-body {
  padding: var(--space-4) var(--space-5) var(--space-5);
}

.records-card-title {
  margin: 0 0 var(--space-2);
  font-size: var(--fs-card-title);
  line-height: var(--lh-h3);
}

.records-card-title a {
  color: var(--ink);
}

.records-card-line {
  margin: 0 0 var(--space-1);
  color: var(--body);
  font-size: var(--fs-nav);
}

.records-empty {
  color: var(--muted);
}

.record-photo {
  margin: 0 0 var(--space-6);
  line-height: 0;
}

.record-photo img {
  width: 100%;
  max-width: 640px;
  height: auto;
}

.record-facts {
  margin: 0 0 var(--space-7);
}

.record-fact {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-5);
  padding: var(--space-3) 0;
  border-top: 1px solid var(--line);
}

.record-fact dt {
  flex: 0 0 12em;
  color: var(--muted);
}

.record-fact dd {
  flex: 1 1 14em;
  margin: 0;
  color: var(--ink);
}

.record-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.record-text {
  margin: 0 0 var(--space-7);
}

.record-text-title {
  margin: 0 0 var(--space-3);
  font-size: var(--fs-card-title);
}

@media (max-width: 600px) {
  .record-fact dt {
    flex-basis: 100%;
  }
}

.records-more {
  margin: var(--space-5) 0 0;
  font-size: var(--fs-nav);
}

/* css/components/services.css */
/* External service links (growth story 39): a row of buttons under the header
   on the home page and «Вступ», and a plain list above the footer on every
   page. The markup is partials/services; every template links this file and
   its own colours, faces and corners arrive through the tokens. */

.services-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin: 0 auto;
  padding-block: var(--space-4);
  list-style: none;
}

.services--top {
  border-bottom: 1px solid var(--line);
  background: var(--paper);
}

.services-btn {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 var(--space-5);
  border: 1.5px solid var(--accent);
  background: var(--accent);
  color: var(--paper);
  font-size: var(--fs-button);
  font-weight: 600;
  text-decoration: none;
}

.services-btn:hover,
.services-btn:focus-visible {
  background: var(--paper);
  color: var(--accent);
}

.services--foot {
  border-top: 1px solid var(--line);
  background: var(--paper);
}

.services-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--ink);
  font-size: var(--fs-nav);
  text-decoration: underline;
}

/* css/components/doc-protection.css */
/* The signature line under a document in a list. Colours and sizes come
   from the tokens, so it scales with the text. */

.doc-protection {
  display: block;
  margin-top: var(--space-1);
  font-size: calc(var(--fs-text) * 0.91);
  line-height: var(--lh-h3);
  color: var(--muted);
}

/* Above a row whose whole area is the document's link. */
.doc-protection a {
  position: relative;
  white-space: nowrap;
  z-index: 1;
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 0.15em;
}

.doc-protection a:hover {
  color: var(--accent);
}

/* The low-vision mode: the line is meta-sized, like the row above it, and its links are the
   mode's link colour. */
:root[data-theme='low-vision'] .doc-protection {
  font-size: var(--fs-meta-lg);
}

:root[data-theme='low-vision'] .doc-protection a {
  color: var(--accent);
}

/* The copy-protection label sits quietly in front of the signature text; the
   description of a «Лише для читання» file is a paragraph of its own. */
.doc-protection-level {
  font-style: italic;
}

.doc-protection-desc {
  display: block;
  margin-top: var(--space-1);
  max-width: 62ch;
}

/* The low-vision mode: whoever cannot read the pictures of a «Лише для
   читання» file meets its description before the labels. */
:root[data-theme='low-vision'] .doc-protection {
  display: flex;
  flex-direction: column;
}

:root[data-theme='low-vision'] .doc-protection-desc {
  order: -1;
  margin-top: 0;
  margin-bottom: var(--space-1);
}

/* The signature text and its links are one line of running text; a long name or provider
   breaks at a word, never inside it. */
.doc-protection-line {
  overflow-wrap: break-word;
}

/* The short mark by a signed document in the documents collection («Підписано») and the
   «Лише підписані» link under the count. The mark is plain text in the meta row's face and colour,
   no frame, inline after the title (the space in front of it is the partial's own, so a mark that
   starts a line has no indent); each template restyles it to its idea. */
.doc-signed-mark {
  color: var(--muted);
  font-size: var(--fs-meta-lg);
  font-weight: 400;
  white-space: nowrap;
}

.doc-signed-filter {
  margin: var(--space-3) 0;
  font-size: var(--fs-text);
}

.doc-signed-filter a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 0.15em;
}

/* «Перевірка підпису» (/dokument/<file id>/pidpys): the document, what the site checked, how to
   check it oneself. A text column; the sentences carry the result, the tick only repeats it. */
.doc-sign {
  padding-bottom: var(--space-11);
}

.doc-sign-doc,
.doc-sign-text,
.doc-sign-note,
.doc-sign-steps,
.doc-sign-small {
  max-width: 62ch;
  overflow-wrap: break-word;
}

/* The link to the document's page is body-size: links stay at the 15 px floor. */
.doc-sign-doc {
  margin: var(--space-2) 0 0;
  color: var(--muted);
  font-size: var(--fs-text);
}

/* Every link inside the page's text is underlined (not told by colour alone), in the mode's link
   colour in low vision. */
.doc-sign-doc a,
.doc-sign-text a,
.doc-sign-steps a,
.doc-sign-files a {
  text-decoration: underline;
  text-underline-offset: 0.15em;
}

:root[data-theme='low-vision'] .doc-sign-doc a,
:root[data-theme='low-vision'] .doc-sign-text a,
:root[data-theme='low-vision'] .doc-sign-steps a,
:root[data-theme='low-vision'] .doc-sign-files a {
  color: var(--accent);
}

.doc-sign-section {
  margin-top: var(--space-7);
}

/* The page's part outranks the group heading below it (1.12 × the body): at least 1.2 × that, in the
   normal and the low-vision scale alike. */
.doc-sign-h2 {
  margin: 0 0 var(--space-3);
  color: var(--ink);
  font-size: calc(var(--fs-text) * 1.35);
  line-height: var(--lh-h3);
}

/* Several signatures: a part for the detached signature and one for those inside the PDF (its
   heading a step larger than the body, in the heading face, over a rule), a part for each signer
   (its heading bold body text); a long name breaks at a word. In low vision the body is 20 px, so
   the group heading is 22 px and still above it. */
.doc-sign-group,
.doc-sign-signer {
  margin-top: var(--space-5);
}

.doc-sign-group {
  margin-top: var(--space-7);
}

.doc-sign-h3 {
  max-width: 62ch;
}

.doc-sign-gh,
.doc-sign-h3 {
  margin: 0;
  color: var(--ink);
  font-weight: 700;
  overflow-wrap: break-word;
}

.doc-sign-gh {
  padding-top: var(--space-3);
  border-top: 1px solid var(--line);
  font-family: var(--font-heading);
  font-size: calc(var(--fs-text) * 1.12);
  line-height: var(--lh-h3);
}

.doc-sign-h3 {
  font-size: var(--fs-text);
  line-height: var(--lh-text);
}

:root[data-theme='low-vision'] .doc-sign-gh,
:root[data-theme='low-vision'] .doc-sign-h3 {
  max-width: none;
}

.doc-sign-checks,
.doc-sign-files {
  margin: 0;
  padding: 0;
  list-style: none;
}

.doc-sign-checks li {
  display: flex;
  gap: var(--space-3);
  max-width: 62ch;
  margin-top: var(--space-2);
  color: var(--body);
  font-size: var(--fs-text);
  line-height: var(--lh-text);
}

.doc-sign-checks li > span {
  min-width: 0;
  overflow-wrap: break-word;
}

.doc-sign-icon {
  flex: none;
  width: 1.25em;
  height: 1.25em;
  margin-top: 0.2em;
  color: var(--accent);
}

.doc-sign-text,
.doc-sign-note,
.doc-sign-steps {
  margin: var(--space-3) 0 0;
  color: var(--body);
  font-size: var(--fs-text);
  line-height: var(--lh-text);
}

.doc-sign-steps {
  padding-left: 1.4em;
}

.doc-sign-steps li + li {
  margin-top: var(--space-2);
}

.doc-sign-facts {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-1) var(--space-5);
  max-width: 62ch;
  margin: var(--space-5) 0 0;
  font-size: var(--fs-text);
  line-height: var(--lh-text);
}

.doc-sign-facts dt {
  color: var(--muted);
  font-size: var(--fs-meta-lg);
}

.doc-sign-facts dd {
  margin: 0 0 var(--space-3);
  color: var(--ink);
  overflow-wrap: break-word;
}

@media (min-width: 30em) {
  .doc-sign-facts {
    grid-template-columns: max-content minmax(0, 1fr);
  }

  .doc-sign-facts dd {
    margin: 0;
  }
}

.doc-sign-file {
  margin: 0;
}

.doc-sign-button {
  display: inline-block;
  max-width: 100%;
  padding: var(--space-3) var(--space-5);
  border: 2px solid var(--accent);
  color: var(--accent);
  font-size: var(--fs-text);
  font-weight: 700;
  overflow-wrap: break-word;
}

.doc-sign-small {
  margin: var(--space-5) 0 0;
  color: var(--muted);
  font-size: var(--fs-meta-lg);
}

/* The separate-file links are links: body size; only the lead-in above them stays small. */
.doc-sign-files {
  margin-top: var(--space-1);
  font-size: var(--fs-text);
  line-height: var(--lh-text);
}

.doc-sign-files li + li {
  margin-top: var(--space-1);
}

:root[data-theme='low-vision'] .doc-sign-doc,
:root[data-theme='low-vision'] .doc-sign-text,
:root[data-theme='low-vision'] .doc-sign-note,
:root[data-theme='low-vision'] .doc-sign-steps,
:root[data-theme='low-vision'] .doc-sign-small,
:root[data-theme='low-vision'] .doc-sign-checks li,
:root[data-theme='low-vision'] .doc-sign-facts {
  max-width: none;
}

/* css/templates/_base/base-template.css */
/* `_base` — the internal template every other one falls back to for a file
   it does not have (growth story 15). Plain, semantic, on the tokens only:
   the low-vision override of tokens.css repaints all of it. Colour pairs used
   throughout, each readable in both looks: text on --paper (--ink, --body,
   --muted, links --accent), --paper on --blue or --accent (buttons), the
   --chrome-bar-* inks on --chrome-bar (dark bands), --ink on --chrome-tint
   (light bands). A template that inherits a view from _base lists this file
   in its manifest, before its own stylesheet. */

/* ---------- page frame ---------- */

.base-body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.base-main {
  flex: 1 0 auto;
}

.base-page {
  padding-block: var(--space-8) var(--space-10);
}

.page-h1 {
  font-size: clamp(30px, 4vw, 44px);
  line-height: 1.1;
  letter-spacing: var(--ls-heading);
  color: var(--ink);
  margin-bottom: var(--space-5);
  overflow-wrap: break-word;
}

.base-section-title {
  font-size: 22px;
  line-height: 1.25;
  color: var(--ink);
  margin: var(--space-8) 0 var(--space-4);
}

.base-kicker {
  font-size: var(--fs-meta-lg);
  font-weight: 700;
  letter-spacing: var(--ls-overline);
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: var(--space-2);
}

.base-lead {
  font-size: 19px;
  line-height: 1.55;
  color: var(--body);
  margin-bottom: var(--space-4);
}

.base-meta {
  font-size: var(--fs-meta-lg);
  color: var(--muted);
}

.base-meta a {
  color: var(--accent);
  text-decoration: underline;
}

.base-count {
  font-weight: 400;
  color: var(--muted);
  font-size: 14px;
}

.base-empty {
  color: var(--muted);
  padding: var(--space-6) 0;
}

.base-status {
  margin: var(--space-5) 0;
  font-weight: 600;
  color: var(--ink);
}

.base-crumbs {
  font-size: var(--fs-meta-lg);
  color: var(--muted);
  margin-bottom: var(--space-4);
}

.base-crumbs a {
  color: var(--accent);
}

/* Running text: a page's Markdown, a post's body, the about block. */
.base-prose {
  max-width: 72ch;
  color: var(--body);
}

.base-prose > * + * {
  margin-top: var(--space-4);
}

.base-prose h2,
.base-prose h3,
.base-prose h4 {
  color: var(--ink);
  line-height: 1.25;
  margin-top: var(--space-8);
}

.base-prose h2 {
  font-size: 26px;
}

.base-prose h3 {
  font-size: 21px;
}

.base-prose ul,
.base-prose ol {
  padding-left: 1.4em;
}

.base-prose li + li {
  margin-top: var(--space-1);
}

.base-prose a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 0.15em;
}

.base-prose img {
  border-radius: var(--radius-media);
}

/* ---------- buttons and small links ---------- */

.base-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 10px 22px;
  border: 2px solid var(--blue);
  background: var(--blue);
  color: var(--paper);
  font: inherit;
  font-size: var(--fs-button);
  font-weight: 700;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--transition-fast), color var(--transition-fast);
}

.base-button:hover {
  background: var(--blue-900);
  border-color: var(--blue-900);
}

.base-button--ghost {
  background: transparent;
  color: var(--blue);
}

.base-button--ghost:hover {
  background: var(--blue);
  color: var(--paper);
}

.base-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: center;
  margin-top: var(--space-5);
}

.base-more {
  font-weight: 700;
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

/* ---------- the header ---------- */

.base-header {
  background: var(--paper);
  border-bottom: 1px solid var(--line);
}

.base-topline {
  background: var(--chrome-bar);
  color: var(--chrome-bar-ink);
  font-size: var(--fs-meta-lg);
}

.base-topline-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2) var(--space-5);
  min-height: 40px;
  padding-block: var(--space-1);
}

.base-topline a {
  color: var(--chrome-bar-strong);
}

.base-topline-tools {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
}

.base-toplink {
  font-weight: 700;
  text-decoration: underline;
}

.base-bvi {
  min-height: 32px;
  padding: 4px 12px;
  border: 1px solid currentColor;
  background: transparent;
  color: inherit;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}

.base-topline .base-bvi {
  color: var(--chrome-bar-strong);
}

.base-header-inner {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  min-height: 84px;
  padding-block: var(--space-3);
}

.base-brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  color: var(--ink);
  text-decoration: none;
  flex: none;
}

.base-brand-logo {
  width: 52px;
  height: 52px;
  object-fit: contain;
}

.base-brand-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  background: var(--blue);
  color: var(--paper);
  font-family: var(--font-heading);
  font-size: 24px;
  font-weight: 800;
  border-radius: var(--radius);
}

.base-brand-name {
  display: flex;
  flex-direction: column;
  font-weight: 800;
  font-size: 17px;
  line-height: 1.15;
  letter-spacing: var(--ls-h3);
}

/* The menu: a row of links; a dropdown opens a panel under its item. */
.base-nav {
  flex: 1 1 auto;
}

.base-nav-list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1) var(--space-2);
  list-style: none;
}

.base-nav-item {
  position: relative;
}

.base-nav-link {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-height: 44px;
  padding: 8px 10px;
  border: 0;
  background: none;
  color: var(--ink);
  font: inherit;
  font-size: var(--fs-nav-main);
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}

.base-nav-link:hover,
.base-nav-link.is-active,
.base-nav-link[aria-expanded='true'] {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 0.3em;
}

.base-nav-cta {
  background: var(--accent);
  color: var(--paper);
  padding-inline: 16px;
}

.base-nav-cta:hover {
  color: var(--paper);
  background: var(--blue);
  text-decoration: none;
}

.base-nav-caret {
  font-size: 14px;
}

.base-nav-panel {
  position: absolute;
  top: 100%;
  left: 50%;
  translate: calc(-50% + var(--mega-shift, 0px)) 0;
  z-index: 70;
  display: flex;
  flex-direction: column;
  min-width: 240px;
  padding: var(--space-2);
  background: var(--paper);
  border: 1px solid var(--line-strong);
  box-shadow: 0 12px 28px var(--blue-shadow-a22);
}

.base-nav-panel[hidden] {
  display: none;
}

.base-nav-sublink {
  display: block;
  padding: 10px 12px;
  color: var(--ink);
  text-decoration: none;
}

.base-nav-sublink:hover,
.base-nav-sublink.is-active {
  background: var(--chrome-tint);
  color: var(--accent);
}

/* The current page in a panel: underlined and heavier, not only tinted (the
   tint is gone in the low-vision look). */
.base-nav-sublink[aria-current='page'] {
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 0.3em;
}

.base-search {
  display: flex;
  align-items: stretch;
  gap: 0;
}

.base-search-input {
  min-width: 0;
  width: 190px;
  min-height: 42px;
  padding: 8px 12px;
  border: 1px solid var(--line-strong);
  border-right: 0;
  background: var(--paper);
  color: var(--ink);
  font: inherit;
  font-size: var(--fs-nav);
}

.base-search-button {
  min-height: 42px;
  padding: 8px 14px;
  border: 1px solid var(--blue);
  background: var(--blue);
  color: var(--paper);
  font: inherit;
  font-size: var(--fs-nav);
  font-weight: 700;
  cursor: pointer;
}

.base-search--page {
  max-width: 640px;
  margin-bottom: var(--space-6);
}

.base-search--page .base-search-input {
  flex: 1;
  width: auto;
  font-size: var(--fs-text);
}

.base-menu-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 48px;
  height: 48px;
  margin-left: auto;
  padding: 12px;
  border: 1px solid var(--line-strong);
  background: var(--paper);
  cursor: pointer;
}

.base-menu-toggle-bar {
  display: block;
  height: 2px;
  background: var(--ink);
}

@media (max-width: 899px) {
  .base-header-nav,
  .base-header-search {
    display: none;
  }

  .base-menu-toggle {
    display: inline-flex;
  }

  .base-topline-contacts {
    display: none;
  }
}

/* ---------- the mobile menu overlay (public/js/mobile-menu.js) ---------- */

.mobile-menu-overlay {
  position: fixed;
  inset: 0;
  z-index: 900;
  overflow-y: auto;
  padding: 72px var(--space-5) var(--space-8);
  background: var(--paper);
}

.mobile-menu-overlay[hidden] {
  display: none;
}

/* Without JavaScript the overlay is a plain list under the header (base.css);
   from the tablet edge the header shows the whole menu, so it goes. */
@media (min-width: 900px) {
  html:not(.js) .mobile-menu-overlay {
    display: none;
  }
}

.mobile-menu-close {
  position: absolute;
  top: var(--space-3);
  right: var(--space-4);
  width: 48px;
  height: 48px;
  border: 1px solid var(--line-strong);
  background: var(--paper);
  color: var(--ink);
  font-size: 28px;
  line-height: 1;
  cursor: pointer;
}

.mobile-search {
  display: flex;
  margin-bottom: var(--space-5);
}

.mobile-search-input {
  flex: 1;
  min-width: 0;
  min-height: 46px;
  padding: 8px 12px;
  border: 1px solid var(--line-strong);
  background: var(--paper);
  color: var(--ink);
  font: inherit;
}

.mobile-search-button {
  min-height: 46px;
  padding: 8px 16px;
  border: 1px solid var(--blue);
  background: var(--blue);
  color: var(--paper);
  font: inherit;
  font-weight: 700;
}

/* The ring of a joined search control (field and button, no gap) is drawn wholly inside it, past the
   1 px border, in the control's own text colour: an outward ring would land on its neighbour. A
   template with another border or ring sets its own offset with the same selectors. */
.base-search-input:focus-visible,
.base-search-button:focus-visible,
.mobile-search-input:focus-visible,
.mobile-search-button:focus-visible {
  outline-color: currentColor;
  outline-offset: -4px;
}

/* :where() keeps this at the weight of a bare a, so a template's own
   overlay colours (and .mobile-important) win over it. */
:where(.mobile-menu-overlay) a,
.mobile-about-toggle {
  display: flex;
  align-items: center;
  width: 100%;
  min-height: 52px;
  border: 0;
  border-bottom: 1px solid var(--line);
  background: none;
  color: var(--ink);
  font: inherit;
  font-size: 18px;
  font-weight: 600;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}

/* The current location (aria-current, from the menu's `current`): a bar at
   the start of the row and a heavier weight, the page itself underlined too
   — never the colour alone, and apart from the focus ring, which outlines
   the whole row. The section above the page («true») gets the bar only. */
.mobile-menu-overlay [aria-current] {
  padding-left: var(--space-3);
  border-left: 4px solid var(--accent);
  font-weight: 700;
}

.mobile-menu-overlay [aria-current='page'] {
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 0.3em;
}

.mobile-about-panel {
  padding-left: var(--space-5);
}

/* The expand marker (review 2026-10, SE-13): a plus that becomes a minus, drawn once and
   bound to aria-expanded — on the mobile menu's group buttons and on a template's own
   toggle that carries `base-expand` (a side tree's folded branch). A link has none: the
   marker is what tells a button that opens a list from a row that goes somewhere. Without
   scripts the groups are open and their buttons inert (html:not(.js)): no marker. */
.mobile-about-toggle::after,
.base-expand::after {
  content: '';
  flex: none;
  width: 12px;
  height: 12px;
  margin-left: auto;
  background:
    linear-gradient(currentColor, currentColor) center / 100% 2px no-repeat,
    linear-gradient(currentColor, currentColor) center / 2px 100% no-repeat;
  transition: background-size var(--transition-fast);
}

.mobile-about-toggle[aria-expanded='true']::after,
.base-expand[aria-expanded='true']::after {
  background-size:
    100% 2px,
    0 0;
}

html:not(.js) .mobile-about-toggle::after {
  display: none;
}

.mobile-about-panel[hidden] {
  display: none;
}

.mobile-important {
  color: var(--accent);
}

/* ---------- the announcement strip ---------- */

.announcement {
  background: var(--chrome-tint);
  border-bottom: 1px solid var(--chrome-tint-line);
  color: var(--ink);
}

.announcement--alert {
  border-left: 6px solid var(--error);
}

.announcement-inner {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: baseline;
  padding-block: var(--space-3);
  font-weight: 600;
}

.announcement-icon {
  color: var(--accent);
}

.announcement--alert .announcement-icon {
  color: var(--error);
}

/* The strip's link: after the text, 24 px tall (it is not inside a sentence), underlined; on a phone it
   takes the line under the text. At any width it drops to its own line, and a long label wraps, when it
   does not fit beside the text. */
.announcement-inner > * {
  min-width: 0;
}

.announcement-inner .announcement-link {
  display: inline-flex;
  flex: 0 1 auto;
  max-width: 100%;
  overflow-wrap: break-word;
  align-items: center;
  min-height: 24px;
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 0.15em;
}

/* ---------- a page inside a dropdown: the section's menu on the left ---------- */

.base-with-nav {
  display: grid;
  grid-template-columns: 240px minmax(0, 1fr);
  gap: var(--space-8);
  align-items: start;
  padding-block: var(--space-8) 0;
}

.base-with-nav-main > .container,
.base-with-nav-main .container {
  max-width: none;
  padding-inline: 0;
}

.base-with-nav-main .base-page {
  padding-top: 0;
}

.section-nav {
  border-top: 3px solid var(--blue);
  padding-top: var(--space-3);
}

.section-nav-title {
  font-weight: 800;
  color: var(--ink);
  margin-bottom: var(--space-2);
}

.section-nav ul {
  list-style: none;
}

.section-nav a {
  display: block;
  padding: 8px 10px;
  border-left: 3px solid transparent;
  color: var(--body);
  font-size: var(--fs-nav-side);
}

.section-nav a:hover,
.section-nav a.active {
  border-left-color: var(--accent);
  color: var(--accent);
  background: var(--chrome-tint);
}

@media (max-width: 899px) {
  .base-with-nav {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-5);
    padding-top: var(--space-5);
  }

  .section-nav ul {
    display: flex;
    gap: var(--space-2);
    overflow-x: auto;
  }

  .section-nav a {
    white-space: nowrap;
    border-left: 0;
    border-bottom: 3px solid transparent;
  }

  .section-nav a.active {
    border-bottom-color: var(--accent);
  }
}

/* ---------- an info page's opening ---------- */

.base-opening {
  background: var(--chrome-tint);
  border-bottom: 1px solid var(--chrome-tint-line);
  color: var(--ink);
}

.base-opening-inner {
  display: grid;
  gap: var(--space-8);
  align-items: center;
  padding-block: var(--space-8);
}

.base-opening--photo .base-opening-inner {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}

.base-opening-title {
  margin-bottom: var(--space-3);
}

.base-opening-counters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-5);
  margin-top: var(--space-3);
}

.base-opening-counter {
  color: var(--accent);
  text-decoration: underline;
}

.base-opening-media img {
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  border-radius: var(--radius-media);
}

@media (max-width: 899px) {
  .base-opening--photo .base-opening-inner {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ---------- the home page's blocks ---------- */

.base-block {
  padding-block: var(--space-8);
}

.base-block + .base-block {
  border-top: 1px solid var(--line);
}

.base-block-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2) var(--space-5);
  margin-bottom: var(--space-5);
}

.base-block-title {
  font-size: clamp(24px, 3vw, 32px);
  line-height: 1.15;
  letter-spacing: var(--ls-heading);
  color: var(--ink);
}

.base-hero {
  background: var(--chrome-tint);
  border-bottom: 1px solid var(--chrome-tint-line);
}

.base-hero-inner {
  display: grid;
  gap: var(--space-8);
  align-items: center;
  padding-block: var(--space-10);
}

.base-hero--photo .base-hero-inner {
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
}

.base-hero-title {
  font-size: clamp(34px, 5vw, var(--fs-h1));
  line-height: var(--lh-h1);
  letter-spacing: var(--ls-heading);
  color: var(--ink);
  overflow-wrap: break-word;
}

.base-hero-tagline {
  margin-top: var(--space-4);
  font-size: var(--fs-tagline);
  line-height: 1.4;
  color: var(--body);
}

.base-hero-lead {
  margin-top: var(--space-4);
  max-width: 60ch;
}

.base-hero-media img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--radius-media);
}

@media (max-width: 899px) {
  .base-hero--photo .base-hero-inner {
    grid-template-columns: minmax(0, 1fr);
  }

  .base-hero-inner {
    padding-block: var(--space-8);
  }
}

/* Cards: posts, albums, related posts. The title's link covers the card. */
.base-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(240px, 100%), 1fr));
  gap: var(--space-7);
  list-style: none;
}

.base-card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}

.base-card-media img {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
}

.base-card-body {
  padding: var(--space-4) var(--space-5) var(--space-5);
}

.base-card-title {
  font-size: var(--fs-card-title);
  line-height: 1.3;
  color: var(--ink);
  overflow-wrap: break-word;
}

.base-card-link {
  color: var(--ink);
  text-decoration: none;
}

.base-card-link:hover {
  color: var(--accent);
  text-decoration: underline;
}

.base-card .base-card-link::after {
  content: '';
  position: absolute;
  inset: 0;
}

.base-card:focus-within {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.base-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(220px, 100%), 1fr));
  gap: var(--space-4);
  list-style: none;
}

.base-tile {
  position: relative;
  padding: var(--space-5);
  border: 1px solid var(--line);
  border-top: 4px solid var(--blue);
  border-radius: var(--radius);
}

.base-tile--accent {
  border-top-color: var(--accent);
}

.base-tile-link {
  display: block;
  font-weight: 800;
  font-size: 18px;
  color: var(--ink);
}

.base-tile-link::after {
  content: '';
  position: absolute;
  inset: 0;
}

.base-tile-note {
  display: block;
  margin-top: var(--space-1);
  font-size: var(--fs-meta-lg);
  color: var(--muted);
}

.base-feature {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
  gap: var(--space-7);
  align-items: center;
}

.base-feature-media img {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: var(--radius-media);
}

@media (max-width: 767px) {
  .base-feature {
    grid-template-columns: minmax(0, 1fr);
  }
}

.base-agenda {
  display: grid;
  gap: var(--space-4);
  list-style: none;
}

.base-agenda-item {
  display: grid;
  grid-template-columns: 72px minmax(0, 1fr);
  gap: var(--space-4);
  align-items: start;
}

.base-date {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 72px;
  padding: var(--space-2);
  border: 2px solid var(--blue);
  color: var(--blue);
  line-height: 1.1;
  text-align: center;
}

.base-date-day {
  font-size: 26px;
  font-weight: 800;
}

.base-date-month {
  font-size: var(--fs-meta-sm);
  font-weight: 700;
  text-transform: uppercase;
}

.base-quick {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(200px, 100%), 1fr));
  gap: var(--space-3);
  list-style: none;
}

.base-quick-link {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 60px;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  color: var(--ink);
  font-weight: 600;
}

.base-quick-link:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.base-quick-icon {
  flex: none;
  width: 26px;
  height: 26px;
  color: var(--accent);
}

.base-figures {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(160px, 100%), 1fr));
  gap: var(--space-5);
  list-style: none;
}

.base-figure {
  display: flex;
  flex-direction: column;
}

.base-figure-value {
  font-family: var(--font-heading);
  font-size: 44px;
  font-weight: 800;
  line-height: 1;
  color: var(--blue);
}

.base-figure-label {
  color: var(--body);
}

/* «Партнери»: a grid of equal columns — two on a phone, one where even two
   would not fit (320 px, a zoomed narrow window), as many as fit from 900 px.
   Every item starts at the top of its row: the logo in a slot of a fixed
   height, centred in it, and the name in its own row under it, so a long
   name grows its item downward and never moves its logo. */
.base-logos {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 140px), 1fr));
  gap: var(--space-6) var(--space-5);
  align-items: start;
  list-style: none;
}

@media (min-width: 900px) {
  .base-logos {
    grid-template-columns: repeat(auto-fill, minmax(min(180px, 100%), 1fr));
  }
}

.base-logo {
  min-width: 0;
}

.base-logo-link {
  display: block;
}

.base-logos .partner {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  width: 100%;
}

.partner-logo {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 72px;
}

.partner-logo img {
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

.base-logos .partner-name {
  max-width: none;
  overflow-wrap: break-word;
}


/* Partners: the name under the logo, so it stays when the logo does not load. */
.partner {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  max-width: 100%;
  text-align: center;
}

.partner-name {
  max-width: 180px;
  font-size: var(--fs-nav);
  line-height: 1.3;
  overflow-wrap: break-word;
}

.base-banner {
  display: grid;
  gap: var(--space-7);
  align-items: center;
  padding: var(--space-7);
  background: var(--chrome-tint);
  border: 1px solid var(--chrome-tint-line);
  border-radius: var(--radius);
}

.base-banner--image {
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
}

.base-banner-media img {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: var(--radius-media);
}

@media (max-width: 899px) {
  .base-banner--image {
    grid-template-columns: minmax(0, 1fr);
  }
}

.base-contacts {
  display: grid;
  gap: var(--space-8);
}

.base-contacts--map {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr);
}

@media (max-width: 899px) {
  .base-contacts--map {
    grid-template-columns: minmax(0, 1fr);
  }
}

.base-facts {
  display: grid;
  gap: var(--space-3);
}

.base-fact dt {
  font-size: var(--fs-meta-lg);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
}

.base-fact dd {
  color: var(--ink);
}

.base-fact a,
.base-contact-lines a {
  color: var(--accent);
}

/* A phone or an e-mail in the page body is a link by more than its colour; the top line and the
   footers (outside main) keep their own rules. */
main .base-fact a,
main .base-contact-lines a {
  text-decoration: underline;
  text-underline-offset: 0.15em;
}

.base-map iframe {
  display: block;
  width: 100%;
  border: 1px solid var(--line);
}

.base-map-links {
  margin-top: var(--space-2);
  font-size: var(--fs-meta-lg);
}

.base-map-links a {
  color: var(--accent);
  text-decoration: underline;
}

/* ---------- documents ---------- */

.base-doc-list {
  list-style: none;
  border-top: 1px solid var(--line);
}

.base-doc {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-1) var(--space-5);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--line);
}

/* The title and the «Підписано» mark after it are one flex item, so the mark follows the title and
   never takes the row's free space; the signature line is a row of its own under them. */
.base-doc-head {
  min-width: 0;
}

.base-doc > .doc-protection {
  flex: 0 0 100%;
  margin-top: 0;
}

.base-doc-link {
  font-weight: 600;
  color: var(--ink);
  overflow-wrap: break-word;
}

.base-doc-link:hover {
  color: var(--accent);
  text-decoration: underline;
}

.base-doc-groups {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
  gap: var(--space-6);
  margin-top: var(--space-6);
}

.base-doc-group-title {
  font-size: 17px;
  color: var(--ink);
  margin-bottom: var(--space-2);
}

.base-link-list {
  list-style: none;
}

.base-link-list li + li {
  margin-top: var(--space-1);
}

.base-link-list a {
  color: var(--accent);
  text-decoration: underline;
}

/* The page a document of the documents collection hangs on (story 26). */
.base-doc-page {
  color: inherit;
  text-decoration: underline;
}

.base-doc-page:hover {
  color: var(--accent);
}

/* ---------- the two collections (story 26) ---------- */

.base-collection-intro {
  margin-bottom: var(--space-6);
}

/* The filters: a plain GET form (partials/collection-filters), its fields
   side by side while they fit. */
.base-collection-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-4) var(--space-5);
  margin-bottom: var(--space-5);
  padding: var(--space-5);
  background: var(--paper-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.base-collection-filter {
  flex: 0 1 220px;
  min-width: 0;
}

.base-collection-filter--wide {
  flex: 1 1 260px;
}

.base-collection-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4);
}

/* The sentence under the filters that says «Сторінка» was reset because the chosen «Тип» has no
   document on it; empty (and out of the way) when nothing was dropped. */
.base-collection-note {
  margin: calc(-1 * var(--space-2)) 0 var(--space-4);
  color: var(--ink);
  font-size: var(--fs-meta-lg);
  font-weight: 600;
}

.base-collection-note:empty {
  display: none;
}

.base-collection-reset {
  color: var(--accent);
  font-weight: 600;
  text-decoration: underline;
}

.base-collection-result {
  margin-bottom: var(--space-4);
  color: var(--muted);
}

/* The page an album comes from, on the albums collection. */
.base-card-source {
  margin-top: var(--space-1);
}

/* The «Фотоальбоми» and «Люди» chapters of a page (story 26). */
.chp-albums,
.chp-people {
  margin-top: var(--space-5);
}

@media (max-width: 899px) {
  .base-collection-filter,
  .base-collection-filter--wide {
    flex: 1 1 100%;
  }
}

/* ---------- filters: chips shared by feeds and the calendar ---------- */

.base-filters {
  display: grid;
  gap: var(--space-2);
  margin-bottom: var(--space-6);
}

.chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  list-style: none;
}

.filter-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 36px;
  padding: 6px 14px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-button);
  background: var(--paper);
  color: var(--ink);
  font: inherit;
  font-size: var(--fs-nav);
  text-decoration: none;
  cursor: pointer;
}

.filter-chip:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.filter-chip.is-active {
  background: var(--blue);
  border-color: var(--blue);
  color: var(--paper);
}

/* ---------- feeds and rows ---------- */

.base-lead-story {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-7);
  align-items: center;
  padding-bottom: var(--space-7);
  border-bottom: 1px solid var(--line);
}

.base-lead-story--photo {
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
}

.base-lead-story-media img {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: var(--radius-media);
}

.base-lead-story-title {
  font-size: clamp(24px, 3vw, 34px);
  line-height: 1.15;
  margin-bottom: var(--space-2);
  overflow-wrap: break-word;
}

@media (max-width: 899px) {
  .base-lead-story--photo {
    grid-template-columns: minmax(0, 1fr);
  }
}

.base-rows {
  list-style: none;
}

.base-row {
  display: flex;
  gap: var(--space-5);
  padding: var(--space-5) 0;
  border-bottom: 1px solid var(--line);
}

.base-row-media {
  flex: none;
  width: 200px;
}

.base-row-media img {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: var(--radius-media);
}

.base-row-title {
  font-size: 20px;
  line-height: 1.3;
  margin: var(--space-1) 0;
  overflow-wrap: break-word;
}

.base-row-title .base-card-link {
  color: var(--ink);
}

.base-row-summary {
  color: var(--body);
}

@media (max-width: 599px) {
  .base-row-media {
    width: 96px;
  }

  .base-row-title {
    font-size: 17px;
  }
}

.base-pagination {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3) var(--space-5);
  margin: var(--space-6) 0;
}

.base-pagination-link {
  font-weight: 700;
  color: var(--accent);
  text-decoration: underline;
}

.base-pagination-status {
  color: var(--muted);
}

/* ---------- a post ---------- */

.base-progress {
  display: none;
}

.has-reading-progress .base-progress {
  display: block;
  position: fixed;
  inset: 0 0 auto;
  z-index: 1200;
  height: 4px;
  pointer-events: none;
}

.base-progress-bar {
  display: block;
  height: 100%;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: 0 50%;
}

.base-article {
  max-width: 860px;
}

.base-article-head {
  margin-bottom: var(--space-6);
}

.base-byline a {
  color: var(--accent);
  text-decoration: underline;
}

.base-byline {
  color: var(--body);
  margin-top: var(--space-2);
}

.base-article-cover {
  margin: 0 0 var(--space-7);
}

.base-article-cover img {
  width: 100%;
  border-radius: var(--radius-media);
  cursor: zoom-in;
}

.base-article-body {
  font-size: 18px;
}

.base-article-foot {
  display: grid;
  gap: var(--space-5);
  margin-top: var(--space-8);
  padding-top: var(--space-5);
  border-top: 1px solid var(--line);
}

.base-related {
  margin-top: var(--space-8);
}

.news-share {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

.news-share-label {
  font-weight: 700;
  color: var(--ink);
  margin-right: var(--space-2);
}

.news-share-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 38px;
  padding: 6px 12px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-button);
  background: var(--paper);
  color: var(--ink);
  font: inherit;
  font-size: var(--fs-nav);
  cursor: pointer;
}

.news-share-link:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.news-share-link svg {
  width: 18px;
  height: 18px;
}

/* Authors under a post (#188) and an author's page. */
.news-section-title {
  font-size: 22px;
  color: var(--ink);
  margin-bottom: var(--space-4);
}

.author-cards {
  margin-top: var(--space-8);
}

.author-cards-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(260px, 100%), 1fr));
  gap: var(--space-5);
}

.author-card {
  display: flex;
  gap: var(--space-4);
  align-items: flex-start;
  padding: var(--space-4);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.author-card-name {
  font-size: 18px;
  color: var(--ink);
}

.author-card-link {
  color: var(--ink);
  text-decoration: underline;
}

.author-card-sign,
.author-card-more {
  font-size: var(--fs-meta-lg);
  color: var(--muted);
}

.author-card-more {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.author-card-roles {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

.author-role {
  font-size: var(--fs-meta-sm);
  font-weight: 700;
  text-transform: uppercase;
  color: var(--accent);
}

.author-av {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--chrome-tint);
  color: var(--ink);
  font-weight: 800;
  vertical-align: middle;
}

.author-av img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.author-av--xs {
  width: 24px;
  height: 24px;
  font-size: 10px;
}

.author-av--hero {
  width: 120px;
  height: 120px;
  font-size: 36px;
}

.base-author {
  display: flex;
  gap: var(--space-6);
  align-items: flex-start;
  margin-bottom: var(--space-6);
}

@media (max-width: 599px) {
  .base-author {
    flex-direction: column;
  }
}

.news-arrow {
  width: 14px;
  height: 14px;
  flex: none;
}

/* ---------- people ---------- */

.base-banner-photo img {
  width: 100%;
  max-width: 900px;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  margin-bottom: var(--space-6);
  border-radius: var(--radius-media);
}

.base-people {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr));
  gap: var(--space-5);
  list-style: none;
  margin: var(--space-6) 0;
}

.base-person {
  display: flex;
  gap: var(--space-4);
  align-items: flex-start;
}

.base-person-photo {
  flex: none;
  width: 96px;
}

.base-person-photo img {
  width: 96px;
  height: 96px;
  object-fit: cover;
  border-radius: var(--radius-media);
}

.base-person--lead {
  margin-bottom: var(--space-6);
  align-items: center;
}

.base-person--lead .base-person-photo,
.base-person--lead .base-person-photo img {
  width: 140px;
  height: 140px;
}

.base-person-name {
  font-size: 19px;
  line-height: 1.25;
  color: var(--ink);
}

.base-person-role {
  color: var(--body);
}

.base-person-bio {
  margin-top: var(--space-2);
  color: var(--body);
}

/* The director's card and a photo placeholder inside the chapter layout. */
.director-card {
  display: flex;
  gap: var(--space-5);
  align-items: center;
  margin-bottom: var(--space-6);
}

.director-photo {
  width: 140px;
  height: 140px;
  overflow: hidden;
  flex: none;
}

.director-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.director-name {
  font-size: 22px;
  color: var(--ink);
}

.photo-slot {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--paper-2);
  border: 1px solid var(--line);
  color: var(--muted);
}

/* ---------- gallery ---------- */

.base-cards--albums {
  grid-template-columns: repeat(auto-fill, minmax(min(260px, 100%), 1fr));
}

/* ---------- the chapter layout of an info page (#183) ---------- */

.section-page {
  padding-block: var(--space-8) var(--space-10);
}

.chp-bar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: var(--space-4);
  margin-bottom: var(--space-7);
  padding-block: var(--space-2);
  background: var(--paper);
  border-bottom: 1px solid var(--line);
}

.chp-bar-label {
  font-size: var(--fs-meta-sm);
  font-weight: 700;
  text-transform: uppercase;
  color: var(--muted);
}

.chp-bar-list {
  display: flex;
  gap: var(--space-2);
  overflow-x: auto;
  list-style: none;
}

.chp-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 36px;
  padding: 6px 12px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-button);
  color: var(--ink);
  white-space: nowrap;
}

.chp-chip.is-active {
  background: var(--blue);
  border-color: var(--blue);
  color: var(--paper);
}

.chp-chip-count {
  font-size: 14px;
}

.chp {
  margin-bottom: var(--space-9);
  scroll-margin-top: 72px;
}

.chp-head {
  display: flex;
  gap: var(--space-4);
  align-items: baseline;
  margin-bottom: var(--space-5);
  padding-bottom: var(--space-2);
  border-bottom: 2px solid var(--ink);
}

/* A title with a long word wraps inside the row instead of widening it. */
.chp-head-copy {
  min-width: 0;
}

.chp-num {
  font-family: var(--font-heading);
  font-size: 32px;
  font-weight: 800;
  color: var(--accent);
}

.chp-title {
  font-size: 26px;
  color: var(--ink);
}

.chp-meta {
  font-size: var(--fs-meta-lg);
  color: var(--muted);
}

.chp-text-body,
.director-text {
  max-width: 72ch;
}

.chp-text-body > * + *,
.director-text > * + * {
  margin-top: var(--space-4);
}

.chp-news-tools {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}

.chp-years {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.chp-year,
.chp-report-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 36px;
  padding: 6px 12px;
  border: 1px solid var(--line-strong);
  color: var(--ink);
}

.chp-year.is-active {
  background: var(--blue);
  border-color: var(--blue);
  color: var(--paper);
}

.chp-report-link svg {
  width: 16px;
  height: 16px;
}

.chp-years-single {
  color: var(--muted);
}

/* A column narrower than one card («Зошит» at 320 px leaves 218 px) holds one card at its width. */
.chp-news-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(260px, 100%), 1fr));
  gap: var(--space-5);
  list-style: none;
}

.chp-news-list > li {
  position: relative;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}

.chp-news-media img {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
}

.news-frame {
  display: block;
}

.chp-news-copy {
  padding: var(--space-4);
}

.chp-news-date {
  display: block;
  font-size: var(--fs-meta-lg);
  color: var(--muted);
}

.chp-news-day::after {
  content: ' ';
}

.chp-news-title {
  font-size: 18px;
  line-height: 1.3;
}

.chp-news-link {
  color: var(--ink);
}

.chp-news-link::after {
  content: '';
  position: absolute;
  inset: 0;
}

.chp-news-summary {
  margin-top: var(--space-2);
  color: var(--body);
}

/* Every card shows its summary: three lines at most beside the photo. */
.chp-news:not(.is-featured) .chp-news-summary {
  display: -webkit-box;
  overflow: hidden;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
}

.chp-news-more {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-top: var(--space-2);
  color: var(--accent);
  font-weight: 700;
}

.chp-news-foot {
  margin-top: var(--space-5);
}

.news-flag {
  display: inline-block;
  padding: 2px 8px;
  background: var(--accent);
  color: var(--paper);
  font-size: var(--fs-meta-sm);
  font-weight: 700;
  text-transform: uppercase;
}

.chp-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 42px;
  padding: 8px 18px;
  border: 2px solid var(--blue);
  background: var(--paper);
  color: var(--blue);
  font: inherit;
  font-weight: 700;
  cursor: pointer;
}

.chp-btn[hidden] {
  display: none;
}

.chp-docs {
  list-style: none;
  border-top: 1px solid var(--line);
}

.chp-doc {
  display: flex;
  gap: var(--space-4);
  align-items: center;
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--line);
}

.chp-doc[hidden] {
  display: none;
}

.chp-doc-type {
  flex: none;
  min-width: 48px;
  padding: 4px 6px;
  border: 1px solid var(--line-strong);
  color: var(--ink);
  font-size: var(--fs-meta-sm);
  font-weight: 700;
  text-align: center;
  text-transform: uppercase;
}

.chp-doc-copy {
  flex: 1;
  min-width: 0;
}

.chp-doc-link {
  font-weight: 600;
  color: var(--ink);
}

.chp-doc-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  font-size: var(--fs-meta-lg);
  color: var(--muted);
}

.chp-doc-dl svg,
.chp-icon {
  width: 20px;
  height: 20px;
  color: var(--accent);
}

/* ---------- the calendar (partials/events-days) ---------- */

.base-events {
  margin-top: var(--space-6);
}

.events-day {
  margin-bottom: var(--space-5);
}

.events-day-title {
  font-size: 18px;
  color: var(--ink);
  padding-bottom: var(--space-1);
  border-bottom: 1px solid var(--line);
  margin-bottom: var(--space-3);
}

.events-list {
  list-style: none;
  display: grid;
  gap: var(--space-3);
}

.events-item-title {
  font-size: 18px;
}

.events-item-title a {
  color: var(--ink);
  text-decoration: underline;
}

.events-item-meta {
  font-size: var(--fs-meta-lg);
  color: var(--muted);
}

.events-item-summary {
  color: var(--body);
}

/* ---------- search results ---------- */

.base-result-list {
  list-style: none;
}

.base-result {
  padding: var(--space-4) 0;
  border-bottom: 1px solid var(--line);
}

.base-result-title {
  font-size: 19px;
  font-weight: 700;
  color: var(--accent);
  text-decoration: underline;
}

.base-result-snippet {
  color: var(--body);
}

.base-result mark {
  background: var(--accent);
  color: var(--paper);
}

/* ---------- forms: contacts, the contact result ---------- */

.base-form {
  display: grid;
  gap: var(--space-4);
  max-width: 640px;
}

.form-group {
  display: grid;
  gap: var(--space-1);
}

.form-group label {
  font-weight: 600;
  color: var(--ink);
}

.form-group input,
.form-group select,
.form-group textarea {
  width: 100%;
  min-height: 44px;
  padding: 10px 12px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--paper);
  color: var(--ink);
  font: inherit;
}

.form-group .is-invalid {
  border-color: var(--error);
  border-width: 2px;
}

.field-error {
  color: var(--error);
  font-weight: 600;
  font-size: var(--fs-meta-lg);
}

.field-error[hidden] {
  display: none;
}

.honeypot-field {
  position: absolute;
  left: -10000px;
  top: -10000px;
}

.draft-preview-banner {
  margin-bottom: var(--space-5);
  padding: var(--space-3) var(--space-4);
  border: 2px solid var(--accent);
  background: var(--chrome-tint);
  color: var(--ink);
  font-weight: 600;
}

.contact-result {
  padding-block: var(--space-8) var(--space-10);
}

.contact-result-message {
  margin-bottom: var(--space-5);
}

/* The box of a refused or failed send: the heading, what happened and, for a
   refused form, the fields to fix. It takes the focus when the page opens. */
.contact-result-errors {
  margin-bottom: var(--space-6);
  padding-left: var(--space-4);
  border-left: 3px solid var(--error);
}

.contact-result-errors ul {
  margin: 0 0 var(--space-4);
  padding-left: var(--space-5);
}

/* The links of the box and of the way out are told from the text by more than colour. */
.contact-result :is(.contact-result-errors, .contact-result-reach) a {
  text-decoration: underline;
}

.contact-result-reach {
  margin-bottom: var(--space-6);
}

/* The focus ring stands clear of the box's own edge. */
.contact-result-errors:focus {
  outline-offset: var(--space-2);
}

/* A link in the box keeps the field's label in view. */
.contact-result .form-group :is(input, textarea) {
  scroll-margin-top: 3em;
}

/* «Панорама»'s own button classes, used by the pages that moved to _base
   unchanged (contact-result, section-report, contact-block). */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 10px 22px;
  border: 2px solid var(--blue);
  font: inherit;
  font-size: var(--fs-button);
  font-weight: 700;
  cursor: pointer;
}

.btn-primary {
  background: var(--blue);
  color: var(--paper);
}

.btn-outline {
  background: transparent;
  color: var(--blue);
}

.text-page-contact {
  display: grid;
  gap: var(--space-2);
  justify-items: start;
  margin-top: var(--space-8);
  padding-top: var(--space-5);
  border-top: 1px solid var(--line);
}

.text-page-contact a:not([class]) {
  color: var(--accent);
  text-decoration: underline;
}

/* ---------- /prozorist and the printable report ---------- */

.transparency-page {
  padding-block: var(--space-8) var(--space-10);
}

.transparency-lead {
  max-width: 72ch;
  color: var(--body);
  margin-bottom: var(--space-5);
}

.transparency-list {
  padding-left: 1.4em;
}

.transparency-item {
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--line);
}

.transparency-link {
  font-weight: 700;
  color: var(--accent);
  text-decoration: underline;
}

.transparency-meta {
  font-size: var(--fs-meta-lg);
  color: var(--muted);
}

.section-report {
  padding-block: var(--space-8) var(--space-10);
}

.section-report-back a {
  color: var(--accent);
}

.section-report-kicker {
  font-size: var(--fs-meta-lg);
  font-weight: 700;
  text-transform: uppercase;
  color: var(--accent);
}

.section-report-title {
  font-size: 34px;
  color: var(--ink);
}

.section-report-year {
  color: var(--muted);
}

.section-report-tools {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-3);
  margin: var(--space-5) 0;
}

.section-report-table {
  overflow-x: auto;
}

.section-report-table table {
  width: 100%;
  border-collapse: collapse;
}

.section-report-table th,
.section-report-table td {
  padding: 8px 10px;
  border: 1px solid var(--line-strong);
  text-align: left;
  vertical-align: top;
}

.section-report-date {
  white-space: nowrap;
}

.section-report-link a {
  color: var(--accent);
  overflow-wrap: break-word;
}

/* ---------- the footer ---------- */

.base-footer {
  margin-top: var(--space-10);
  background: var(--chrome-bar);
  color: var(--chrome-bar-ink);
}

.base-footer a {
  color: var(--chrome-bar-strong);
}

.base-footer-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr));
  gap: var(--space-7);
  padding-block: var(--space-9);
}

.base-footer-name {
  font-weight: 800;
  font-size: 18px;
  color: var(--chrome-bar-strong);
  margin-bottom: var(--space-2);
}

.base-footer-tagline {
  margin-top: var(--space-2);
}

.base-footer-title {
  font-size: var(--fs-meta-lg);
  font-weight: 700;
  letter-spacing: var(--ls-overline);
  text-transform: uppercase;
  color: var(--chrome-bar-strong);
  margin-bottom: var(--space-3);
}

.base-footer-links {
  list-style: none;
}

.base-footer-links li + li {
  margin-top: var(--space-1);
}

.base-footer-links a,
.base-footer-cta {
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

.base-contact-lines {
  list-style: none;
}

.base-footer-contacts li + li {
  margin-top: var(--space-1);
}

.base-footer .base-contact-label {
  color: var(--chrome-bar-ink);
}

.base-footer-cta {
  font-weight: 700;
}

.base-footer-bottom {
  padding-block: var(--space-4);
  border-top: 1px solid var(--chrome-bar-line);
  font-size: var(--fs-meta-lg);
}

.base-topline-contacts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-5);
}

.base-topline .base-contact-label {
  opacity: 0.85;
}

/* The social icons (partials/social-icons), wherever a template puts them. */
.chrome-social {
  display: flex;
  gap: var(--space-2);
  margin-block: var(--space-3);
}

.chrome-social a {
  display: inline-flex;
  width: 32px;
  height: 32px;
}

.chrome-social svg {
  width: 100%;
  height: 100%;
  fill: currentColor;
}

/* Contact lines on the dark bands keep the bands' own link colour. */
.base-topline .base-contact-lines a,
.base-footer .base-contact-lines a {
  color: var(--chrome-bar-strong);
}

/* A block whose heading stands alone (no «all …» link beside it). */
.base-block > .base-block-title {
  margin-bottom: var(--space-5);
}

/* «Нижній колонтитул: Світлий» of «Оформлення». */
.theme-footer-light .base-footer {
  background: var(--chrome-tint);
  border-top: 1px solid var(--chrome-tint-line);
  color: var(--body);
}

.theme-footer-light .base-footer a,
.theme-footer-light .base-footer .base-contact-lines a,
.theme-footer-light .base-footer-name,
.theme-footer-light .base-footer-title,
.theme-footer-light .base-footer .base-contact-label {
  color: var(--ink);
}

.theme-footer-light .base-footer-bottom {
  border-top-color: var(--chrome-tint-line);
}

/* ---------- shared fixes (QA, 2026-10) ----------
   Every template that keeps `_base`'s markup picks these up; a template's
   own stylesheet loads after this one and still has the last word. */

/* .link-cue — the contract every template keeps (docs/dev/templates.md):
   a link whose own text names where it leads — «Усі …», a document, a
   document section or a page, the section nav, an event, a post, an album,
   a search result — answers the pointer and the keyboard alike: the accent
   and a thicker underline, never the colour alone; the focus ring of
   base.css comes on top. A template's own markup opts in by the class. */
.link-cue:hover,
.link-cue:focus-visible {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 0.2em;
}

.base-doc-group-title a {
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

/* «Партнери»: with a link, the name (.partner-name) is in the text colour
   and takes the links' hover/focus cue. */
.base-logo-link {
  color: var(--ink);
  text-decoration: none;
}

.base-logo-link:hover .partner-name,
.base-logo-link:focus-visible .partner-name {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 0.2em;
}

/* A dropdown opens under its own item, from its left edge (mega-menu.js
   still shifts it back inside the window), and a page named like the
   dropdown heads the panel as its overview, set apart by a rule. */
.base-nav-panel {
  left: 0;
  translate: var(--mega-shift, 0px) 0;
}

.base-nav-panel .base-nav-overview {
  margin-bottom: var(--space-1);
  border-bottom: 1px solid var(--line);
  color: var(--ink);
  font-weight: 800;
}

/* The labels of the contacts («Адреса», «Телефон») and of an event («Коли»,
   «Де»): sentence case in the text colour, set apart by weight alone — no
   grey tracked capitals, which read as faint at this size. */
.base-fact dt {
  color: var(--ink);
  font-size: var(--fs-nav-side);
  letter-spacing: 0;
  text-transform: none;
}

.base-topline .base-contact-label {
  opacity: 1;
  font-weight: 600;
}

/* No scripts: the desktop dropdown opens on hover and on keyboard focus, in
   every template over this menu (partials/main-nav). With scripts the `js`
   class is on <html> and mega-menu.js does it, as before. The bridge keeps the
   hover across a template's gap between the item and its panel. */
html:not(.js) .mega-menu-wrap:hover > .base-nav-panel[hidden],
html:not(.js) .mega-menu-wrap:focus-within > .base-nav-panel[hidden] {
  display: flex;
}

html:not(.js) .mega-menu-wrap > .base-nav-panel::before {
  content: '';
  position: absolute;
  inset: auto 0 100%;
  height: 8px;
}

/* ---------- the first screen on a phone: the name once, one line of announcement ----------
   At 480 px and below a hero title that only restates the school's name (partials/home/
   hero-title) shows the short name at one line's size — the header already names
   the school — and announcement.js clamps the strip to one line with «…» and a
   «Читати» button that opens the rest. Wider, nothing changes. */

.hero-title-short {
  display: none;
}

@media (max-width: 480px) {
  .hero-title-full {
    display: none;
  }

  .hero-title-short {
    display: block;
    font-size: var(--fs-h2-phone);
    line-height: 1.15;
    overflow-wrap: break-word;
  }

  .announcement-inner {
    flex-wrap: wrap;
  }

  .announcement-inner .announcement-link {
    flex: 0 1 auto;
    flex-basis: 100%;
    max-width: 100%;
    overflow-wrap: break-word;
  }

  .announcement--short .announcement-inner {
    align-items: center;
  }

  .announcement--short:not(.announcement--open) .announcement-text {
    flex: 1 1 0;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .announcement-more {
    flex: none;
    min-height: 24px;
    padding: 0 var(--space-1);
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    font-size: var(--fs-nav-side);
    text-decoration: underline;
    text-underline-offset: 0.15em;
    cursor: pointer;
  }
}

/* The keyboard focus ring from the token: the same ring as base.css, and a rule with a class in
   front of it still wins. The fallback keeps the ring when tokens.css is an older copy. */
:focus-visible {
  outline: var(--focus-ring, 2px solid var(--accent));
  outline-offset: 2px;
}

/* An album slide after the first has no file until the frame is about to show it
   (partials/album, public/js/album.js): until then it is a blank frame, not the
   alt text of a picture that is not there. Only once the script runs (album--ready):
   without it the stage clips those slides anyway, and their frame links keep the
   photo's alt text as their name. */
.album--ready .album-img:not([src]) {
  visibility: hidden;
}

/* The no-media states: a person without a photo and a post without a cover keep their media column
   (a quiet tinted tile on the chrome tokens, so the text of every card and every row starts at the
   same x); a lead story without a cover is a deliberate text-only block with an accent rule. */
.base-person-photo--blank {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 96px;
  background: var(--chrome-tint);
  border: 1px solid var(--chrome-tint-line);
  border-radius: var(--radius-media);
  color: var(--blue);
  font-family: var(--font-heading);
  font-size: 36px;
  font-weight: 700;
  line-height: 1;
}

.base-person--lead .base-person-photo--blank {
  font-size: 52px;
}

.base-row-blank {
  display: block;
  width: 100%;
  aspect-ratio: 3 / 2;
  background: repeating-linear-gradient(
    135deg,
    var(--chrome-tint) 0 14px,
    var(--chrome-tint-line) 14px 28px
  );
  border-radius: var(--radius-media);
}

.base-lead-story:not(.base-lead-story--photo) .base-lead-story-copy {
  max-width: 46rem;
  padding-left: var(--space-5);
  border-left: 4px solid var(--accent);
}

:root[data-theme='low-vision'] .base-row-blank {
  background-image: none;
  border: 1px solid var(--chrome-tint-line);
}

/* On paper the section menu is hidden (base.css), so its column goes too. */
@media print {
  .base-with-nav {
    display: block;
  }
}

/* ---------- the photo style (growth story 72, S14b) ----------
   «Оформлення фото» of a post's cover and a page's header photo: the class
   photo-style--<value> sits on the element that holds the photo alone (never on
   a figure with its caption). 'frame': an inset border of the accent colour;
   'tint': a layer of the primary colour at 18 % multiplied over the photo;
   'duotone' (kept for later, the panel does not offer it): grey under the tint.
   The layer is a ::after that catches no clicks (the photo still opens in the
   viewer) and takes the corners of the box it covers (border-radius: inherit),
   so a box whose photo carries the media radius clips to it. The frame is
   --photo-frame wide: 6 px, 3 px on a thumbnail. A template refines these in its
   own folder where its idea calls for it. Low vision shows the photo as it is. */
:where(.photo-style--frame, .photo-style--tint, .photo-style--duotone) {
  position: relative;
}

.photo-style--frame::after,
.photo-style--tint::after,
.photo-style--duotone::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
}

/* The boxes whose photo carries the media radius itself: the box takes it and
   clips, so the layer's corners are the photo's. */
:where(.base-lead-story-media)[class*='photo-style--'],
:where(.base-opening-media)[class*='photo-style--'],
:where(.base-row-media)[class*='photo-style--'],
:where(.base-person-photo)[class*='photo-style--'],
:where(.base-banner-photo)[class*='photo-style--'],
:where(.base-article-cover > div)[class*='photo-style--'] {
  border-radius: var(--radius-media);
  overflow: clip;
}

/* A card's photo is clipped by the card: rounded at the top, square below. */
.base-card-media[class*='photo-style--'] {
  border-radius: var(--radius) var(--radius) 0 0;
}

.base-row-media {
  --photo-frame: 3px;
}

.photo-style--frame::after {
  box-sizing: border-box;
  border: var(--photo-frame, 6px) solid var(--accent);
}

.photo-style--tint::after,
.photo-style--duotone::after {
  background: var(--blue);
  opacity: 0.18;
  mix-blend-mode: multiply;
}

.photo-style--duotone img {
  filter: grayscale(1);
}

/* A row's media box stretches to the row's height (a long title on a phone):
   styled, it keeps to the photo, or the layer covers the empty space below it. */
.base-row-media[class*='photo-style--'] {
  align-self: flex-start;
}

/* No filter of its own here: the photo stays grey like every other picture in
   this mode (base.css), and duotone is that same grey. */
:root[data-theme='low-vision'] [class*='photo-style--']::after {
  display: none;
}

/* css/templates/panorama/panorama.css */
/* «Панорама» — «Горизонт» (the 2026-10 spike). Like an old panoramic
   photograph: the school's photo is a long, low strip right under a light
   header, nothing set on it, and under it the school's name large in a quiet
   serif (the heading face, Spectral in the preset «Горизонт») as the page's
   title. The photo is the horizon line of every page — a thin strip on the
   inner pages. Then a calm site on white: sections as a list of large links,
   news as rows of photo and title, documents across the full width, the
   contacts once, in the footer. No arrows, no eyebrows, no shadows.
   Over _base (base-template.css); every colour a token. */

/* ---------- type and the page ---------- */

.panorama-body {
  --ink: var(--panorama-ink);
  color: var(--body);
}

/* The heading face in one weight, mixed case: the serif carries the name. */
.panorama-body :is(h1, h2, h3, h4, .page-h1, .hero-title, .logo-wordmark, .footer-org-name) {
  font-weight: 400;
  letter-spacing: var(--ls-heading);
}

.panorama-body .page-h1 {
  font-size: clamp(32px, 4vw, 50px);
  line-height: 1.08;
  overflow-wrap: break-word;
}

/* Links in the school's colour, as weak as a bare `a`. */
:where(.panorama-body) a {
  color: var(--accent);
}

.panorama-body .base-kicker {
  font-size: var(--fs-meta-lg);
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--muted);
}

.panorama-body :is(.base-block-title, .base-card-title, .panorama-block-title, .panorama-row-title) {
  overflow-wrap: break-word;
}

/* ---------- the header: one light brand row, the menu under it ---------- */

.panorama-header {
  position: relative;
  z-index: 60;
  background: var(--paper);
}

/* The row holds still whatever the name: the mark and the tools hang from
   the top of one band (--panorama-band). */
.panorama-brandrow {
  --panorama-band: 48px;
  display: flex;
  align-items: flex-start;
  gap: var(--space-3) var(--space-5);
  min-height: 64px;
  padding-block: var(--space-2);
}

.panorama-brand {
  display: inline-flex;
  align-items: flex-start;
  gap: var(--space-3);
  min-width: 0;
  margin-right: auto;
  color: var(--ink);
  text-decoration: none;
}

.panorama-brand-logo,
.panorama-brand-mark {
  margin-top: calc((var(--panorama-band) - 40px) / 2);
}

.panorama-brand-logo {
  flex: none;
  width: 40px;
  height: 40px;
  object-fit: contain;
}

.panorama-brand-mark {
  display: inline-flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  background: var(--blue);
  color: var(--paper);
  font-family: var(--font-heading);
  font-size: 22px;
  border-radius: var(--radius);
}

/* The admin's lines one under another, in full, in the band's middle. */
.panorama-body .panorama-brand-name {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-width: 0;
  min-height: var(--panorama-band);
  font-size: 20px;
  line-height: 1.15;
  letter-spacing: 0;
  overflow-wrap: break-word;
}

.panorama-brand-line {
  display: block;
}

.panorama-body .panorama-brand--long .panorama-brand-name {
  font-size: 17px;
}

.panorama-tools {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 0 var(--space-3);
  min-height: var(--panorama-band);
}

/* The tools are plain words with a middle dot between them, no box, no
   underline until hovered. */
.panorama-tools .panorama-tool {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--ink);
  font: inherit;
  font-size: 15px;
  font-weight: 400;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}

.panorama-tools .panorama-tool:hover {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 0.28em;
}

/* The highlighted link may be long: it wraps at its spaces instead of
   pushing the row wider than a 320 px screen, and only a word longer than the
   whole row is broken. A grid track that may shrink to nothing lets the text
   wrap inside the row (a flex row would hold it at its longest word). */
.panorama-tools .panorama-tool--key {
  display: inline-grid;
  grid-template-columns: minmax(0, max-content);
  align-items: center;
  min-width: 0;
  max-width: 100%;
  padding-block: var(--space-2);
  color: var(--accent);
  font-weight: 600;
  white-space: normal;
  overflow-wrap: break-word;
}

/* The search is the shared form made small; the sheet carries it on a phone. */
.panorama-tools .panorama-search {
  margin-inline: var(--space-3);
}

.panorama-tools .base-search-input {
  width: 150px;
  min-height: 36px;
  padding: 4px 10px;
  font-size: 15px;
}

.panorama-tools .base-search-button {
  min-height: 36px;
  padding: 4px 12px;
  border-color: var(--ink);
  background: var(--ink);
  font-size: 15px;
}

/* The switch while the low-vision look is on (it then reads «Звичайна версія»). */
:root[data-theme='low-vision'] .panorama-tools .base-bvi {
  font-weight: 700;
}

.panorama-menu-toggle {
  display: none;
  min-height: 44px;
  padding: 0 var(--space-4);
  border: 1px solid var(--line-strong);
  background: var(--paper);
  color: var(--ink);
  font: inherit;
  font-size: 15px;
  cursor: pointer;
}

.panorama-navrow {
  border-top: 1px solid var(--line);
}

/* Tight enough that the recommended menu (five dropdowns, «Новини»,
   «Контакти» and «Вступ») keeps to one row from 1280 px. */
.panorama-nav .base-nav-list {
  gap: 0;
  margin-inline: -8px;
}

.panorama-nav .base-nav-link {
  min-height: 46px;
  padding-inline: 8px;
  font-size: 15.5px;
  font-weight: 500;
}

.panorama-nav .base-nav-link:hover,
.panorama-nav .base-nav-link.is-active,
.panorama-nav .base-nav-link[aria-expanded='true'] {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--accent);
  text-decoration-thickness: 2px;
  text-underline-offset: 0.45em;
}

.panorama-nav .base-nav-cta {
  min-height: 34px;
  margin-left: var(--space-2);
  padding: 4px 14px;
  border-radius: var(--radius-button);
  color: var(--paper);
}

.panorama-nav .base-nav-cta:hover {
  color: var(--paper);
  text-decoration: none;
}

/* The dropdown hangs straight under its item, flat: an edge, no shadow. */
.panorama-nav .base-nav-panel {
  left: 0;
  translate: var(--mega-shift, 0px) 0;
  min-width: 260px;
  padding: var(--space-1) 0;
  border: 1px solid var(--line-strong);
  box-shadow: none;
}

.panorama-nav .base-nav-sublink {
  padding: 10px var(--space-4);
}

.panorama-nav .base-nav-sublink:hover,
.panorama-nav .base-nav-sublink.is-active {
  background: var(--panorama-fog);
  color: var(--ink);
}

.panorama-body .panorama-brand--longer .panorama-brand-name {
  font-size: 15px;
  line-height: 1.06;
}

/* The nine items of the recommended menu fit one row from 1100 px, with the links
   a little tighter than at 1280; below that the header is the compact one («Меню» and the
   sheet), never a second row with one lone item. */
@media (min-width: 1100px) and (max-width: 1279px) {
  .panorama-nav .base-nav-list {
    margin-inline: -5px;
  }

  .panorama-nav .base-nav-link {
    padding-inline: 5px;
  }

  .panorama-nav .base-nav-cta {
    margin-left: var(--space-1);
    padding: 4px 10px;
  }
}

/* Without scripts the compact header still has its menu: the plain list in the sheet. */
@media (min-width: 900px) and (max-width: 1099px) {
  html:not(.js) .panorama-body .mobile-menu-overlay {
    display: block;
  }
}

@media (max-width: 1099px) {
  .panorama-brandrow {
    --panorama-band: 52px;
    flex-wrap: wrap;
    gap: 0 var(--space-3);
    min-height: 56px;
    padding-block: var(--space-2) 0;
  }

  /* «Меню» keeps its place on the brand row: the name takes what is left,
     its lines run on as one text, in full, beside the mark. */
  .panorama-brand {
    flex: 1 1 0;
    min-height: 52px;
  }

  .panorama-body .panorama-brand-name {
    display: block;
    min-height: 0;
    padding-block: max(0px, calc((var(--panorama-band) - 1.15em) / 2));
    font-size: 18px;
  }

  .panorama-brand-line {
    display: inline;
  }

  .panorama-body .panorama-brand--long .panorama-brand-name {
    font-size: 16px;
  }

  .panorama-body .panorama-brand--longer .panorama-brand-name {
    font-size: 15px;
    line-height: 1.2;
  }

  .panorama-menu-toggle {
    display: inline-flex;
    flex: none;
    align-items: center;
    margin-top: calc((var(--panorama-band) - 44px) / 2);
    white-space: nowrap;
  }

  /* The tools take a thin line of their own under the name. */
  .panorama-tools {
    order: 3;
    flex: 1 0 100%;
    min-height: 0;
    justify-content: flex-start;
    border-top: 1px solid var(--line);
  }

  .panorama-tools .panorama-tool {
    min-height: 40px;
    font-size: 14.5px;
  }

  .panorama-tools .panorama-search {
    display: none;
  }

  .panorama-tools .panorama-tool + .panorama-tool,
  .panorama-tools .panorama-tool--key {
    margin-right: var(--space-4);
  }

  .panorama-navrow {
    display: none;
  }
}

/* A long name on a phone keeps the mark: the name runs on in full beside it. */
@media (max-width: 599px) {
  :root[data-theme='low-vision'] .panorama-body .panorama-brand--longer .panorama-brand-name {
    font-size: 15px;
  }
}

/* ---------- the mobile menu: a sheet of large serif links ---------- */

.panorama-sheet {
  padding: 0 var(--space-5) var(--space-8);
}

.panorama-sheet-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  min-height: 64px;
  margin-bottom: var(--space-4);
  border-bottom: 1px solid var(--line);
}

.panorama-sheet-name {
  min-width: 0;
  font-family: var(--font-heading);
  font-size: 19px;
  color: var(--ink);
  overflow-wrap: break-word;
}

.panorama-sheet .panorama-sheet-close {
  position: static;
  flex: none;
  width: auto;
  height: 44px;
  padding: 0 var(--space-4);
  font-size: 15px;
}

.panorama-sheet .mobile-search-button {
  border-color: var(--ink);
  background: var(--ink);
}

.panorama-sheet-nav a,
.panorama-sheet-nav .mobile-about-toggle {
  min-height: 54px;
  font-family: var(--font-heading);
  font-size: 22px;
  font-weight: 400;
}

.panorama-sheet-nav .mobile-about-panel a {
  min-height: 46px;
  font-family: var(--font-body);
  font-size: 17px;
}

/* The menu's call to action keeps its fill in the sheet. */
.panorama-body .panorama-sheet-nav .panorama-sheet-cta {
  min-height: 48px;
  margin-block: var(--space-2);
  padding: 4px var(--space-5);
  border: 0;
  border-radius: var(--radius-button);
  background: var(--blue);
  color: var(--paper);
  font-family: var(--font-body);
  font-size: 18px;
  font-weight: 600;
}

/* The current location keeps _base's bar and weight in the sheet (the
   heading face's lighter weight above would drop the second). */
.panorama-sheet-nav [aria-current] {
  font-weight: 700;
}

.panorama-sheet-nav a[aria-current='page'],
.panorama-sheet-nav .mobile-about-toggle[aria-expanded='true'],
.panorama-body .panorama-sheet-nav .mobile-important {
  color: var(--accent);
}

/* ---------- the strip: the photo as the horizon ---------- */

.panorama-strip {
  position: relative;
  overflow: hidden;
  background: var(--chrome-bar);
}

.panorama-strip img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--fx, 50%) var(--fy, 45%);
}

/* The school's accent as a 2 px rule under every strip: the horizon line. */
.panorama-strip {
  border-bottom: 2px solid var(--accent);
}

.panorama-strip--hero {
  height: 33.333vw;
}

/* The inner pages' strip stays low: it is the horizon, not a banner. */
.panorama-strip--thin {
  height: 72px;
}

/* No photo on an inner page: a thin wash of the school's colour. */
.panorama-strip--thin.panorama-strip--plain {
  height: 32px;
  background: linear-gradient(to bottom, var(--paper), var(--blue-a12));
}

@media (min-width: 600px) {
  .panorama-strip--thin {
    height: 96px;
  }
}

@media (min-width: 900px) {
  .panorama-strip--hero {
    height: min(33.333vw, calc(100vh - 320px));
    min-height: 260px;
  }

  .panorama-strip--thin {
    height: clamp(120px, 9vw, 140px);
  }

  .panorama-strip--thin.panorama-strip--plain {
    height: 40px;
  }
}

@media (max-width: 599px) {
  .panorama-strip--hero {
    height: 50vw;
  }
}

/* No photo on the home page: a low wash of the school's colour fading into
   white, the name inside it. */
.panorama-hero--plain {
  background: linear-gradient(to bottom, var(--blue-a12), var(--paper)) top / 100%
    clamp(150px, 16vw, 200px) no-repeat;
}

.panorama-hero--plain .panorama-title {
  padding-top: clamp(40px, 5vw, 64px);
}

/* The one moment: the strip unrolls from its middle, once, as soon as its
   photo is ready to draw. The folded pose is set before the first paint and
   the unrolling starts with the photo (panorama-pose.js), so the strip never
   stands half-open while the photo arrives. Reduced motion and the low-vision
   look always draw the photo whole. */
@keyframes panorama-unroll {
  from {
    clip-path: inset(0 50% 0 50%);
  }

  to {
    clip-path: inset(0 0 0 0);
  }
}

.panorama-unroll .panorama-strip--hero {
  clip-path: inset(0 50% 0 50%);
}

.panorama-unroll-go .panorama-strip--hero {
  animation: panorama-unroll 800ms cubic-bezier(0.25, 0.7, 0.25, 1) both;
}

:root[data-theme='low-vision'] .panorama-strip--hero {
  clip-path: none;
  animation: none;
}

@media (prefers-reduced-motion: reduce) {
  .panorama-unroll .panorama-strip--hero {
    clip-path: none;
    animation: none;
  }
}

/* ---------- the title under the strip ---------- */

/* The name and the tagline on the left 7/12; the right 5/12 holds the lead
   and the buttons, only when there is a lead. */
.panorama-title {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: var(--space-3) var(--space-8);
  align-items: start;
  padding-block: var(--space-6) var(--space-7);
}

.panorama-title-name {
  min-width: 0;
}

.panorama-title-name .panorama-hero-tagline {
  max-width: 40ch;
  margin-top: var(--space-3);
}

.panorama-body .panorama-hero-title {
  font-size: clamp(36px, 4.6vw, 62px);
  line-height: 1.04;
  letter-spacing: -0.012em;
  color: var(--ink);
  overflow-wrap: break-word;
}

.panorama-body .panorama-hero-title--long {
  font-size: clamp(32px, 3.6vw, 48px);
  line-height: 1.08;
}

.panorama-body .panorama-hero-title--longer {
  font-size: clamp(28px, 2.9vw, 38px);
  line-height: 1.12;
}

.panorama-title-aside {
  padding-top: 0.45em;
}

.panorama-hero-tagline {
  font-size: 19px;
  line-height: 1.45;
  color: var(--ink);
}

.panorama-hero-lead {
  margin-top: var(--space-2);
  color: var(--body);
}

.panorama-hero-lead p + p {
  margin-top: var(--space-2);
}

.panorama-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3) var(--space-5);
  margin-top: var(--space-4);
}

.panorama-body .panorama-button {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 8px 20px;
  border: 1px solid var(--accent);
  border-radius: var(--radius-button);
  background: var(--paper);
  color: var(--accent);
  font-weight: 600;
  text-decoration: none;
}

/* The menu's «Вступ» is the one filled button; the others are outlined. */
.panorama-body .panorama-button:hover {
  background: var(--panorama-fog);
  color: var(--ink);
}

.panorama-textlink,
.panorama-more {
  font-weight: 500;
  text-decoration: underline;
  text-underline-offset: 0.22em;
}

@media (max-width: 899px) {
  .panorama-title {
    grid-template-columns: minmax(0, 1fr);
    padding-block: var(--space-5) var(--space-6);
  }

  .panorama-title-aside {
    padding-top: 0;
  }

  .panorama-hero-tagline {
    font-size: 17px;
  }
}

/* ---------- a page with chapters reads as the same page ---------- */

/* A page's first document adds its chapter and restyles nothing (#396): the
   plain heading (partials/page-heading), the text set as .base-prose, no
   chapter numbers; the text's own head, and the people's when they open the
   page or follow the text, kept for screen readers only. */
.panorama-main .panorama-page-heading {
  display: flow-root;
  padding-bottom: 0;
}

.panorama-main .panorama-page-heading + .section-page {
  padding-top: 0;
}

.panorama-body .chp-num {
  display: none;
}

.panorama-body .section-page > #pro-rozdil > .chp-head,
.panorama-body .section-page > #lyudy:first-of-type > .chp-head,
.panorama-body .section-page > #pro-rozdil + #lyudy > .chp-head {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: 0;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* After the text the people come as close as under a people page's intro:
   the text chapter's own margin (_base) less the difference. */
.panorama-body .section-page > #pro-rozdil + #lyudy {
  margin-top: calc(var(--space-6) - var(--space-9));
}

.panorama-body .chp-text-body {
  color: var(--body);
}

.panorama-body .chp-text-body > * {
  margin-bottom: 0;
}

.panorama-body .chp-text-body > * + * {
  margin-top: var(--space-4);
}

.panorama-body .chp-text-body h2,
.panorama-body .chp-text-body h3,
.panorama-body .chp-text-body h4 {
  color: var(--ink);
  line-height: 1.25;
  margin-top: var(--space-8);
}

.panorama-body .chp-text-body h2 {
  font-size: 26px;
}

.panorama-body .chp-text-body h3 {
  font-size: 21px;
}

.panorama-body .chp-text-body ul,
.panorama-body .chp-text-body ol {
  padding-left: 1.4em;
}

.panorama-body .chp-text-body li + li {
  margin-top: var(--space-1);
}

.panorama-body .chp-text-body a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 0.15em;
}

.panorama-body .chp-text-body img {
  border-radius: var(--radius-media);
}

/* ---------- the inner pages' title under the thin strip ---------- */

.panorama-opening {
  padding-block: var(--space-7) 0;
}

/* Beside the section menu: the title in the content column, as on a page
   that sets its own. */
.panorama-opening--column {
  padding-block: 0 var(--space-5);
}

.panorama-body .panorama-opening-title {
  margin-bottom: var(--space-3);
}

.panorama-opening-lead {
  max-width: 62ch;
  font-size: 18px;
  line-height: 1.55;
}

.panorama-opening-counters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-5);
  margin-top: var(--space-3);
}

.panorama-opening-counter {
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

.panorama-body .section-nav {
  border-top: 1px solid var(--line);
}

.panorama-body .section-nav-title {
  font-weight: 600;
}

.panorama-body .section-nav a:hover,
.panorama-body .section-nav a:focus-visible,
.panorama-body .section-nav a.active {
  background: var(--panorama-fog);
}

/* The current page: _base's bar and a heavier weight, so it stays apart
   from a hovered or focused link, which only gets the wash. */
.panorama-body .section-nav a[aria-current] {
  font-weight: 700;
}

/* On a phone the section's pages wrap onto lines instead of a strip cut at
   the edge. */
@media (max-width: 899px) {
  .panorama-body .section-nav ul {
    flex-wrap: wrap;
    gap: 0 var(--space-1);
    overflow-x: visible;
  }

  .panorama-body .section-nav a {
    white-space: normal;
  }
}

/* ---------- the home page's blocks: white, a hairline between ---------- */

.panorama-body .base-block {
  padding-block: var(--space-8);
}

.panorama-hero + .base-block {
  border-top: 1px solid var(--line);
  padding-top: var(--space-7);
}

.panorama-block-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2) var(--space-5);
  margin-bottom: var(--space-5);
}

.panorama-body :is(.panorama-block-title, .base-block-title) {
  font-size: clamp(27px, 3vw, 36px);
  line-height: 1.12;
  color: var(--ink);
}

.panorama-meta {
  color: var(--muted);
  font-size: 14px;
}

.panorama-about {
  max-width: 68ch;
}

/* «Розділи сайту»: large serif links on hairlines — three columns, two on a
   tablet, one on a phone. */
.panorama-sections {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  column-gap: var(--space-8);
  list-style: none;
}

.panorama-section {
  padding-block: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--line);
}

.panorama-body .panorama-section-link {
  display: inline-block;
  font-family: var(--font-heading);
  font-size: clamp(22px, 2.2vw, 27px);
  line-height: 1.2;
  color: var(--ink);
  text-decoration: none;
  overflow-wrap: break-word;
}

.panorama-body .panorama-section-link:hover,
.panorama-body .panorama-section-link:focus-visible {
  color: var(--accent);
}

/* An accented section: a small square of the accent before its title. */
.panorama-section--accent .panorama-section-link::before {
  content: '';
  display: inline-block;
  width: 0.36em;
  height: 0.36em;
  margin-right: 0.4em;
  vertical-align: 0.14em;
  background: var(--accent);
}

.panorama-body .panorama-section-link:hover,
.panorama-body .panorama-section-link:focus-visible {
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 0.18em;
}

.panorama-section-note {
  display: block;
  margin-top: 2px;
  color: var(--muted);
  font-size: 14.5px;
}

/* News: rows of a small print and its title, two across. */
.panorama-rows {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-6) var(--space-8);
  list-style: none;
}

.panorama-row {
  display: grid;
  grid-template-columns: 200px minmax(0, 1fr);
  gap: var(--space-5);
  align-items: start;
  padding-top: var(--space-5);
  border-top: 1px solid var(--line);
}

.panorama-row--text {
  grid-template-columns: minmax(0, 1fr);
}

.panorama-row-media img {
  display: block;
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: var(--radius-media);
}

.panorama-body .panorama-row-title {
  margin-top: 2px;
  font-size: 21px;
  line-height: 1.25;
  letter-spacing: 0;
  color: var(--ink);
}

.panorama-body .panorama-row-link {
  color: var(--ink);
  text-decoration: none;
}

.panorama-body .panorama-row-link:hover,
.panorama-body .panorama-row-link:focus-visible {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-thickness: 2px;
}

/* «Документи»: the full width, a ruled list; the groups as one row under it. */
.panorama-files {
  list-style: none;
  border-top: 1px solid var(--line);
}

.panorama-file {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 2px var(--space-8);
  padding-block: var(--space-3);
  border-bottom: 1px solid var(--line);
}

.panorama-body .panorama-file-link {
  flex: 1 1 26rem;
  min-width: 0;
  color: var(--ink);
  font-weight: 600;
  text-decoration: none;
  overflow-wrap: break-word;
}

.panorama-body .panorama-file-link:hover,
.panorama-body .panorama-file-link:focus-visible {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-thickness: 2px;
}

.panorama-file-meta {
  flex: none;
  white-space: nowrap;
}

.panorama-file-type {
  letter-spacing: var(--ls-filetype);
}

.panorama-doc-groups {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr));
  gap: var(--space-5) var(--space-8);
  margin-top: var(--space-7);
}

.panorama-body .panorama-doc-group-title {
  margin-bottom: var(--space-2);
  font-size: 19px;
  letter-spacing: 0;
}

.panorama-doc-group-list {
  list-style: none;
}

.panorama-doc-group-list li + li {
  margin-top: var(--space-1);
}

/* «Найближчі події»: the day in the heading face, the month in words. */
.panorama-agenda {
  display: grid;
  gap: var(--space-4);
  list-style: none;
}

.panorama-agenda-item {
  display: grid;
  grid-template-columns: 64px minmax(0, 1fr);
  gap: var(--space-4);
  align-items: baseline;
  padding-top: var(--space-4);
  border-top: 1px solid var(--line);
}

.panorama-date {
  display: flex;
  flex-direction: column;
  line-height: 1;
}

.panorama-date-day {
  font-family: var(--font-heading);
  font-size: 36px;
  color: var(--ink);
}

.panorama-date-month {
  margin-top: 4px;
  color: var(--muted);
  font-size: 14px;
}

/* The album: its cover one more low strip. */
.panorama-album-media {
  margin-bottom: var(--space-3);
}

.panorama-album-media img {
  display: block;
  width: 100%;
  aspect-ratio: 3 / 1;
  object-fit: cover;
  border-radius: var(--radius-media);
}

/* «Як нас знайти»: the map across the width, one action in the head. */
.panorama-map iframe {
  display: block;
  width: 100%;
  border: 1px solid var(--line);
}

/* «Контакти» without a map: the facts the settings allow, in columns under the
   block's head, a hairline above them like the horizon. One column on a phone. */
.panorama-facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
  gap: var(--space-5) var(--space-8);
  margin: 0;
  padding-top: var(--space-5);
  border-top: 1px solid var(--line);
}

.panorama-fact dt {
  margin-bottom: var(--space-1);
  color: var(--muted);
  font-size: 14px;
}

.panorama-fact {
  min-width: 0;
}

.panorama-fact dd {
  margin: 0;
  font-size: 18px;
  line-height: 1.45;
  overflow-wrap: break-word;
}

/* The other blocks of _base, quieted. «Корисні посилання»: an icon and an
   underlined link per row, no boxes. */
.panorama-body .base-quick {
  gap: 0 var(--space-8);
}

.panorama-body .base-quick-link {
  min-height: 48px;
  padding: var(--space-2) 0;
  border: 0;
  border-radius: 0;
  color: var(--ink);
  font-weight: 400;
}

.panorama-body .base-quick-link span {
  text-decoration: underline;
  text-decoration-color: var(--line-strong);
  text-underline-offset: 0.25em;
}

.panorama-body .base-quick-link:hover {
  color: var(--accent);
}

.panorama-body .base-quick-link:hover span {
  text-decoration-color: currentColor;
}

.panorama-body .base-quick-icon {
  width: 22px;
  height: 22px;
}

.panorama-body .base-figure-value {
  font-weight: 400;
  color: var(--ink);
}

.panorama-body .base-banner {
  background: var(--panorama-fog);
  border-color: var(--panorama-fog-line);
}

/* The banner's button outlined: the menu's «Вступ» stays the one fill. */
.panorama-body .base-banner .base-button {
  border-width: 1px;
  background: transparent;
  color: var(--accent);
  border-color: var(--accent);
}

.panorama-body .base-banner .base-button:hover {
  background: var(--paper);
  color: var(--ink);
}

@media (max-width: 899px) {
  .panorama-rows {
    grid-template-columns: minmax(0, 1fr);
  }

  .panorama-sections {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 599px) {
  .panorama-sections {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (max-width: 599px) {
  .panorama-row {
    grid-template-columns: 112px minmax(0, 1fr);
    gap: var(--space-4);
  }

  .panorama-body .panorama-row-title {
    font-size: 19px;
  }

  .panorama-file-meta {
    white-space: normal;
  }
}

/* ---------- the footer: the contacts, once ---------- */

.panorama-footer {
  margin-top: var(--space-8);
  padding-block: var(--space-8) var(--space-5);
  background: var(--panorama-fog);
  border-top: 1px solid var(--panorama-fog-line);
  color: var(--body);
}

.panorama-footer-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) repeat(auto-fit, minmax(min(180px, 100%), 1fr));
  gap: var(--space-7) var(--space-8);
}

/* A phone: the `about` column across, the groups two to a row and a lone last group across (the
   1.4fr track would be squeezed to a narrow strip); one column in the low-vision look. */
@media (max-width: 599px) {
  .panorama-footer {
    padding-top: var(--space-7);
  }

  .panorama-footer-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-6) var(--space-4);
  }

  .panorama-footer-about,
  .panorama-footer-col:nth-child(even):last-child {
    grid-column: 1 / -1;
  }

  :root[data-theme='low-vision'] .panorama-footer-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

.panorama-body .panorama-footer-name {
  margin-bottom: var(--space-3);
  font-size: 24px;
  line-height: 1.2;
  color: var(--ink);
  overflow-wrap: break-word;
}

.panorama-footer-contacts {
  list-style: none;
  font-size: 15px;
  line-height: 1.6;
}

.panorama-footer .base-contact-label {
  color: var(--muted);
}

.panorama-footer .chrome-social {
  margin-top: var(--space-3);
}

.panorama-footer-action {
  margin-top: var(--space-4);
}

.panorama-body .panorama-footer-cta {
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 0.22em;
}

.panorama-footer-tagline {
  margin-top: var(--space-3);
  color: var(--muted);
  font-size: 14.5px;
}

.panorama-body .panorama-footer-title {
  margin-bottom: var(--space-2);
  font-size: 19px;
  letter-spacing: 0;
  color: var(--ink);
}

.panorama-footer-links {
  list-style: none;
  font-size: 15px;
}

.panorama-footer-links li + li {
  margin-top: var(--space-1);
}

.panorama-footer-bottom {
  margin-top: var(--space-7);
  padding-top: var(--space-4);
  border-top: 1px solid var(--panorama-fog-line);
  color: var(--muted);
  font-size: var(--fs-meta-lg);
}

/* «Темний» нижній колонтитул: the school's colour. */
.theme-footer-dark .panorama-footer {
  background: var(--chrome-bar);
  border-top-color: var(--chrome-bar);
  color: var(--chrome-bar-ink);
}

.theme-footer-dark .panorama-footer :is(.panorama-footer-name, .panorama-footer-title),
.theme-footer-dark .panorama-footer a {
  color: var(--chrome-bar-strong);
}

.theme-footer-dark .panorama-footer :is(.base-contact-label, .panorama-footer-tagline) {
  color: var(--chrome-bar-ink);
}

.theme-footer-dark .panorama-footer-bottom {
  border-top-color: var(--chrome-bar-line);
  color: var(--chrome-bar-ink);
}

/* ---------- the low-vision mode ---------- */

/* Commissioner instead of the serif: a little weight back, display sizes
   capped so a long name still fits; the strip's photo is grey (base.css). */
:root[data-theme='low-vision']
  .panorama-body
  :is(h1, h2, h3, h4, .page-h1, .hero-title, .logo-wordmark, .footer-org-name) {
  font-weight: 700;
}

:root[data-theme='low-vision'] .panorama-body .panorama-hero-title {
  font-size: clamp(32px, 4vw, 52px);
  line-height: 1.12;
}

:root[data-theme='low-vision'] .panorama-strip {
  border-bottom-color: var(--line);
}

/* The inner pages' strip is decoration only: gone in this mode. */
:root[data-theme='low-vision'] .panorama-strip--thin {
  display: none;
}

/* No photo: a black band with a yellow edge under it, the name inside. */
:root[data-theme='low-vision'] .panorama-hero--plain {
  background: var(--paper);
  border-bottom: 2px solid var(--line);
}

:root[data-theme='low-vision'] .panorama-hero--plain + .base-block {
  border-top: 0;
}

:root[data-theme='low-vision'] .panorama-body .panorama-tool {
  text-decoration: underline;
  text-decoration-color: currentColor;
  text-underline-offset: 0.28em;
}

:root[data-theme='low-vision'] .panorama-body .panorama-sheet-nav .panorama-sheet-cta {
  background: var(--blue);
  color: var(--paper);
}

@media (max-width: 899px) {
  :root[data-theme='low-vision'] .panorama-tools .panorama-tool {
    font-size: 17px;
  }
}

/* «Перевірка підпису»: the serif in one weight read as body text — a semibold step for the group and
   the signer headings (Spectral SemiBold), the page's part a step larger. Low vision keeps the
   bold of the rule above. */
:root:not([data-theme='low-vision']) .panorama-body :is(.doc-sign-gh, .doc-sign-h3) {
  font-weight: 600;
}

.panorama-body .doc-sign-h2 {
  font-size: calc(var(--fs-card-title) * 1.2);
}

/* The photo style (S14b): on the full-bleed horizon strip the frame is a rule
   along its top only, square; the row photo is a thumbnail. */
.panorama-strip.photo-style--frame::after {
  border-width: 3px 0 0;
  border-radius: 0;
}

.panorama-row-media {
  --photo-frame: 3px;
}

/* The row photo carries the media radius itself: the styled box takes it and clips. */
.panorama-row-media[class*='photo-style--'] {
  border-radius: var(--radius-media);
  overflow: clip;
}
